package fi.helsinki.cs.tmc.cli.backend;

import fi.helsinki.cs.tmc.cli.io.EnvironmentUtil;
import fi.helsinki.cs.tmc.cli.io.WorkDir;

import fi.helsinki.cs.tmc.core.configuration.TmcSettings;
import fi.helsinki.cs.tmc.core.domain.Course;

import com.google.common.base.Optional;
import fi.helsinki.cs.tmc.core.domain.OauthCredentials;
import fi.helsinki.cs.tmc.core.domain.Organization;
import fi.helsinki.cs.tmc.spyware.SpywareSettings;
import org.apache.http.impl.conn.SystemDefaultRoutePlanner;

import java.nio.file.Path;
import java.util.Locale;

public class Settings implements TmcSettings, SpywareSettings {

    private WorkDir workDir;
    private Account account;

    public Settings() {
        this.account = new Account();
    }

    public Settings(String username, String password, Organization organization) {
        this.account = new Account(username, password, organization);
    }

    /**
     * This method is used for changing the main settings object.
     * @param account account that has the login info
     */
    public void setAccount(Account account) {
        if (account == null) {
            account = new Account();
        }
        this.account = account;
    }

    public Account getAccount() {
        return account;
    }

    public void setWorkDir(WorkDir workDir) {
        this.workDir = workDir;
    }

    @Override
    public String getServerAddress() {
        return account.getServerAddress();
    }

    @Override
    public void setServerAddress(String address) {
       account.setServerAddress(address);
    }

    @Override
    public Optional<String> getPassword() {
        return account.getPassword();
    }

    @Override
    public void setPassword(Optional<String> password) {
            account.setPassword(password);
    }

    @Override
    public Optional<String> getUsername() {
        return account.getUsername();
    }

    @Override
    public boolean userDataExists() {
        return getUsername().isPresent() && getPassword().isPresent();
    }

    @Override
    public Optional<Course> getCurrentCourse() {
        return account.getCurrentCourse();
    }

    @Override
    public String clientName() {
        return "tmc_cli";
    }

    @Override
    public String clientVersion() {
        return EnvironmentUtil.getVersion();
    }

    @Override
    public Path getTmcProjectDirectory() {
        return workDir.getTmcDirectory();
    }

    @Override
    public Locale getLocale() {
        return new Locale("EN");
    }

    @Override
    public SystemDefaultRoutePlanner proxy() {
        return null;
    }

    @Override
    public void setCourse(Optional<Course> course) {
        this.account.setCurrentCourse(course);
    }

    @Override
    public Path getConfigRoot() {
        return SettingsIo.getConfigDirectory();
    }

    @Override
    public String hostProgramName() {
        // which command line is used
        return "unknown";
    }

    @Override
    public String hostProgramVersion() {
        return "unknown";
    }

    @Override
    public boolean getSendDiagnostics() {
        return account.getSendDiagnostics();
    }

    public void setSendDiagnostics(boolean value) {
        account.setSendDiagnostics(value);
    }

    @Override
    public Optional<OauthCredentials> getOauthCredentials() {
        return account.getOauthCredentials();
    }

    @Override
    public void setOauthCredentials(Optional<OauthCredentials> credentials) {
        account.setOauthCredentials(credentials);
    }

    @Override
    public void setToken(Optional<String> token) {
        account.setOauthToken(token);
    }

    @Override
    public Optional<String> getToken() {
        return account.getOauthToken();
    }

    @Override
    public Optional<Organization> getOrganization() {
        return account.getOrganization();
    }

    @Override
    public void setOrganization(Optional<Organization> organization) {
        account.setOrganization(organization);
    }

    @Override
    public boolean isSpywareEnabled() {
        return account.getSendAnalytics();
    }

    public void setSpywareEnabled(boolean spywareEnabled) {
        account.setSendAnalytics(spywareEnabled);
    }

    @Override
    public boolean isDetailedSpywareEnabled() {
        return account.getSendDetailedAnalytics();
    }

    public void setDetailedSpywareEnabled(boolean detailedSpywareEnabled) {
        account.setSendDetailedAnalytics(detailedSpywareEnabled);
    }
}

@@ -123,24 +123,83 @@
 o.WorkDir;%0A%0A
+import fi.helsinki.cs.tmc.core.communication.oauth2.Oauth;%0A
 import fi.he
@@ -240,24 +240,24 @@
 mcSettings;%0A
-
 import fi.he
@@ -549,16 +549,212 @@
 Planner;
+%0Aimport org.apache.oltu.oauth2.common.exception.OAuthProblemException;%0Aimport org.apache.oltu.oauth2.common.exception.OAuthSystemException;%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Aimport
@@ -865,16 +865,98 @@
 ings %7B%0A%0A
+    private static final Logger logger = LoggerFactory.getLogger(Settings.class);%0A
     priv
@@ -1444,24 +1444,24 @@
  == null) %7B%0A
-
             
@@ -1495,16 +1495,471 @@
       %7D%0A
+        try %7B%0A            Optional%3CString%3E password = account.getPassword();%0A            if(password.isPresent()) %7B%0A                Oauth.getInstance().fetchNewToken(password.get());%0A                account.setPassword(Optional.absent());%0A                SettingsIo.saveCurrentSettingsToAccountList(this);%0A            %7D%0A        %7D catch (OAuthProblemException %7C OAuthSystemException var1) %7B%0A            logger.warn(%22Settings migration failed.%22);%0A        %7D%0A
         

Migrate password to oauth, update core version