package com.gitblit;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;

import org.apache.wicket.util.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.Constants.AccountType;
import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.ConnectionUtils;
import com.gitblit.utils.StringUtils;
import com.google.gson.Gson;

/**
 * Implementation of an Redmine user service.<br>
 * you can login to gitblit with Redmine user id and api key.
 */
public class RedmineUserService extends GitblitUserService {

    private final Logger logger = LoggerFactory.getLogger(RedmineUserService.class);

    private IStoredSettings settings;

    private String testingJson;

    private class RedmineCurrent {
        private class RedmineUser {
            public String login;
            public String firstname;
            public String lastname;
            public String mail;
        }

        public RedmineUser user;
    }

    public RedmineUserService() {
        super();
    }

    @Override
    public void setup(IStoredSettings settings) {
        this.settings = settings;

        String file = settings.getString(Keys.realm.redmine.backingUserService, "${baseFolder}/users.conf");
        File realmFile = GitBlit.getFileOrFolder(file);

        serviceImpl = createUserService(realmFile);
        logger.info("Redmine User Service backed by " + serviceImpl.toString());
    }

    @Override
    public boolean supportsCredentialChanges() {
        return false;
    }

    @Override
    public boolean supportsDisplayNameChanges() {
        return false;
    }

    @Override
    public boolean supportsEmailAddressChanges() {
        return false;
    }

    @Override
    public boolean supportsTeamMembershipChanges() {
        return false;
    }
    
	 @Override
	protected AccountType getAccountType() {
		return AccountType.REDMINE;
	}

    @Override
    public UserModel authenticate(String username, char[] password) {
		if (isLocalAccount(username)) {
			// local account, bypass Redmine authentication
			return super.authenticate(username, password);
		}

        String jsonString = null;
        try {
        	// first attempt by username/password
        	jsonString = getCurrentUserAsJson(username, password);
        } catch (Exception e1) {
        	logger.warn("Failed to authenticate via username/password against Redmine");
        	try {
        		// second attempt is by apikey
        		jsonString = getCurrentUserAsJson(null, password);
        		username = null;
        	} catch (Exception e2) {
        		logger.error("Failed to authenticate via apikey against Redmine", e2);
        		return null;
        	}
        }
        
        if (StringUtils.isEmpty(jsonString)) {
        	logger.error("Received empty authentication response from Redmine");
        	return null;
        }
        
        RedmineCurrent current = null;
        try {
        	current = new Gson().fromJson(jsonString, RedmineCurrent.class);
        } catch (Exception e) {
        	logger.error("Failed to deserialize Redmine json response: " + jsonString, e);
        	return null;
        }

        if (StringUtils.isEmpty(username)) {
        	// if the username has been reset because of apikey authentication
        	// then use the email address of the user. this is the original
        	// behavior as contributed by github/mallowlabs
        	username = current.user.mail;
        }

        UserModel user = getUserModel(username);
        if (user == null)	// create user object for new authenticated user
        	user = new UserModel(username.toLowerCase());

        // create a user cookie
        if (StringUtils.isEmpty(user.cookie) && !ArrayUtils.isEmpty(password)) {
        	user.cookie = StringUtils.getSHA1(user.username + new String(password));
        }

        // update user attributes from Redmine
        user.accountType = getAccountType();
        user.displayName = current.user.firstname + " " + current.user.lastname;
        user.emailAddress = current.user.mail;
        user.password = ExternalAccount;
        if (!StringUtils.isEmpty(current.user.login)) {
        	// only admin users can get login name
        	// evidently this is an undocumented behavior of Redmine
        	user.canAdmin = true;
        }

        // TODO consider Redmine group mapping for team membership
        // http://www.redmine.org/projects/redmine/wiki/Rest_Users

        // push the changes to the backing user service
        super.updateUserModel(user);

        return user;
    }

    private String getCurrentUserAsJson(String username, char [] password) throws IOException {
        if (testingJson != null) { // for testing
            return testingJson;
        }

        String url = this.settings.getString(Keys.realm.redmine.url, "");
        if (!url.endsWith("/")) {
        	url = url.concat("/");
        }
        HttpURLConnection http;
        if (username == null) {
        	// apikey authentication
        	String apiKey = String.valueOf(password);
        	String apiUrl = url + "users/current.json?key=" + apiKey;
        	http = (HttpURLConnection) ConnectionUtils.openConnection(apiUrl, null, null);
        } else {
        	// username/password BASIC authentication
        	String apiUrl = url + "users/current.json";
        	http = (HttpURLConnection) ConnectionUtils.openConnection(apiUrl, username, password);
        }
        http.setRequestMethod("GET");
        http.connect();
        InputStreamReader reader = new InputStreamReader(http.getInputStream());
        return IOUtils.toString(reader);
    }
    
    /**
     * set json response. do NOT invoke from production code.
     * @param json json
     */
    public void setTestingCurrentUserAsJson(String json) {
        this.testingJson = json;
    }
}
