/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/
package org.apache.ofbiz.passport.user;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.io.IOException;
import java.io.Serializable;
import java.sql.Timestamp;

import javax.transaction.Transaction;

import org.apache.ofbiz.passport.event.GitHubEvents;
import org.apache.ofbiz.passport.user.GitHubUserGroupMapper;
import org.apache.ofbiz.passport.util.PassportUtil;
import org.apache.ofbiz.common.authentication.api.Authenticator;
import org.apache.ofbiz.common.authentication.api.AuthenticatorException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.ServiceUtil;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.transaction.TransactionUtil;
import org.apache.ofbiz.entity.transaction.GenericTransactionException;
import org.apache.ofbiz.entity.util.EntityUtil;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.ofbiz.base.conversion.ConversionException;
import org.apache.ofbiz.base.conversion.JSONConverters.JSONToMap;
import org.apache.ofbiz.base.lang.JSON;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilDateTime;
import org.apache.ofbiz.base.util.UtilValidate;

/**
 * GitHub OFBiz Authenticator
 */
public class GitHubAuthenticator implements Authenticator {

    private static final String module = GitHubAuthenticator.class.getName();

    public static final String props = "gitHubAuth.properties";

    public static final String resource = "PassportUiLabels";

    protected LocalDispatcher dispatcher;

    protected Delegator delegator;

    /**
     * Method called when authenticator is first initialized (the delegator
     * object can be obtained from the LocalDispatcher)
     *
     * @param dispatcher The ServiceDispatcher to use for this Authenticator
     */
    public void initialize(LocalDispatcher dispatcher) {
        this.dispatcher = dispatcher;
        this.delegator = dispatcher.getDelegator();
    }

    /**
     * Method to authenticate a user.
     * 
     * For GitHub users, we only check if the username(userLoginId) exists an 
     * externalAuthId, and the externalAuthId has a valid accessToken in 
     * GitHubUser entity.
     *
     * @param userLoginId   User's login id
     * @param password      User's password
     * @param isServiceAuth true if authentication is for a service call
     * @return true if the user is authenticated
     * @throws org.apache.ofbiz.common.authentication.api.AuthenticatorException
     *          when a fatal error occurs during authentication
     */
    public boolean authenticate(String userLoginId, String password, boolean isServiceAuth) throws AuthenticatorException {
        Map<String, Object> user = null;
        HttpGet getMethod = null;
        try {
            GenericValue userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", userLoginId), false);
            String externalAuthId = userLogin.getString("externalAuthId");
            GenericValue gitHubUser = delegator.findOne("GitHubUser", UtilMisc.toMap("gitHubUserId", externalAuthId), false);
            if (UtilValidate.isNotEmpty(gitHubUser)) {
                String accessToken = gitHubUser.getString("accessToken");
                String tokenType = gitHubUser.getString("tokenType");
                if (UtilValidate.isNotEmpty(accessToken)) {
                    getMethod = new HttpGet(GitHubEvents.ApiEndpoint + GitHubEvents.UserApiUri);
                    user = GitHubAuthenticator.getUserInfo(getMethod, accessToken, tokenType, Locale.getDefault());
                }
            }
        } catch (GenericEntityException e) {
            throw new AuthenticatorException(e.getMessage(), e);
        } catch (AuthenticatorException e) {
            throw new AuthenticatorException(e.getMessage(), e);
        } finally {
            if (getMethod != null) {
                getMethod.releaseConnection();
            }
        }

        Debug.logInfo("GitHub auth called; returned user info: " + user, module);
        return user != null;
    }

    /**
     * Logs a user out
     *
     * @param username User's username
     * @throws org.apache.ofbiz.common.authentication.api.AuthenticatorException
     *          when logout fails
     */
    public void logout(String username) throws AuthenticatorException {
    }

    /**
     * Reads user information and syncs it to OFBiz (i.e. UserLogin, Person, etc)
     *
     * @param userLoginId
     * @throws org.apache.ofbiz.common.authentication.api.AuthenticatorException
     *          user synchronization fails
     */
    public void syncUser(String userLoginId) throws AuthenticatorException {
        Map<String, Object> userMap = getGitHubUserinfo(userLoginId);
        GenericValue system;
        try {
            system = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", "system"), true);
        } catch (GenericEntityException e) {
            throw new AuthenticatorException(e.getMessage(), e);
        }

        GenericValue userLogin;
        try {
            userLogin = EntityUtil.getFirst(delegator.findByAnd("UserLogin", UtilMisc.toMap("externalAuthId", (String) userMap.get("id")), null, false));
        } catch (GenericEntityException e) {
            throw new AuthenticatorException(e.getMessage(), e);
        }

        // suspend the current transaction and load the user
        Transaction parentTx = null;
        boolean beganTransaction = false;

        try {
            try {
                parentTx = TransactionUtil.suspend();
            } catch (GenericTransactionException e) {
                Debug.logError(e, "Could not suspend transaction: " + e.getMessage(), module);
            }

            try {
                beganTransaction = TransactionUtil.begin();

                if (userLogin == null) {
                    // create the user
                    createUser(userMap, system);
                } else {
                    // update the user information
                    updateUser(userMap, system, userLogin);
                }

            } catch (GenericTransactionException e) {
                Debug.logError(e, "Could not suspend transaction: " + e.getMessage(), module);
            } finally {
                try {
                    TransactionUtil.commit(beganTransaction);
                } catch (GenericTransactionException e) {
                    Debug.logError(e, "Could not commit nested transaction: " + e.getMessage(), module);
                }
            }
        } finally {
            // resume/restore parent transaction
            if (parentTx != null) {
                try {
                    TransactionUtil.resume(parentTx);
                    Debug.logVerbose("Resumed the parent transaction.", module);
                } catch (GenericTransactionException e) {
                    Debug.logError(e, "Could not resume parent nested transaction: " + e.getMessage(), module);
                }
            }
        }
    }

    private Map<String, Object> getGitHubUserinfo(String userLoginId) throws AuthenticatorException {
        Map<String, Object> user = null;
        HttpGet getMethod = null;
        try {
            GenericValue userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", userLoginId), false);
            String externalAuthId = userLogin.getString("externalAuthId");
            GenericValue gitHubUser = delegator.findOne("GitHubUser", UtilMisc.toMap("gitHubUserId", externalAuthId), false);
            if (UtilValidate.isNotEmpty(gitHubUser)) {
                String accessToken = gitHubUser.getString("accessToken");
                String tokenType = gitHubUser.getString("tokenType");
                if (UtilValidate.isNotEmpty(accessToken)) {
                    getMethod = new HttpGet(GitHubEvents.ApiEndpoint + GitHubEvents.UserApiUri);
                    user = getUserInfo(getMethod, accessToken, tokenType, Locale.getDefault());
                }
            }
        } catch (GenericEntityException e) {
            throw new AuthenticatorException(e.getMessage(), e);
        } catch (AuthenticatorException e) {
            throw new AuthenticatorException(e.getMessage(), e);
        }
        return user;
    }

    public String createUser(Map<String, Object> userMap) throws AuthenticatorException {
        GenericValue system;
        try {
            system = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", "system"), true);
        } catch (GenericEntityException e) {
            throw new AuthenticatorException(e.getMessage(), e);
        }
        return createUser(userMap, system);
    }
    
    private String createUser(Map<String, Object> userMap, GenericValue system) throws AuthenticatorException {
        // create person + userLogin
        Map<String, Serializable> createPersonUlMap = new HashMap<String, Serializable>();
        String userLoginId = delegator.getNextSeqId("UserLogin");
        if (userMap.containsKey("name")) {
            // use github's name as OFBiz's lastName
            createPersonUlMap.put("lastName", (String) userMap.get("name"));
        }
        if (userMap.containsKey("login")) {
            createPersonUlMap.put("externalAuthId", (String) userMap.get("login"));
        }
        // createPersonUlMap.put("externalId", user.getUserId());
        createPersonUlMap.put("userLoginId", userLoginId);
        createPersonUlMap.put("currentPassword", "[EXTERNAL]");
        createPersonUlMap.put("currentPasswordVerify", "[EXTERNAL]");
        createPersonUlMap.put("userLogin", system);
        Map<String, Object> createPersonResult;
        try {
            createPersonResult = dispatcher.runSync("createPersonAndUserLogin", createPersonUlMap);
        } catch (GenericServiceException e) {
            throw new AuthenticatorException(e.getMessage(), e);
        }
        if (ServiceUtil.isError(createPersonResult)) {
            throw new AuthenticatorException(ServiceUtil.getErrorMessage(createPersonResult));
        }
        String partyId = (String) createPersonResult.get("partyId");

        // give this person a role of CUSTOMER
        GenericValue partyRole = delegator.makeValue("PartyRole", UtilMisc.toMap("partyId", partyId, "roleTypeId", "CUSTOMER"));
        try {
            delegator.create(partyRole);
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            throw new AuthenticatorException(e.getMessage(), e);
        }

        // create email
        if (userMap.containsKey("email")) {
            Map<String, Serializable> createEmailMap = new HashMap<String, Serializable>();
            createEmailMap.put("emailAddress", (String) userMap.get("email"));
            createEmailMap.put("contactMechPurposeTypeId", "PRIMARY_EMAIL");
            createEmailMap.put("partyId", partyId);
            createEmailMap.put("userLogin", system);
            Map<String, Object> createEmailResult;
            try {
                createEmailResult = dispatcher.runSync("createPartyEmailAddress", createEmailMap);
            } catch (GenericServiceException e) {
                throw new AuthenticatorException(e.getMessage(), e);
            }
            if (ServiceUtil.isError(createEmailResult)) {
                throw new AuthenticatorException(ServiceUtil.getErrorMessage(createEmailResult));
            }
        }

        // create security group(s)
        Timestamp now = UtilDateTime.nowTimestamp();
        for (String securityGroup : (new GitHubUserGroupMapper(new String[] {(String) userMap.get("type")}).getSecurityGroups())) {
            // check and make sure the security group exists
            GenericValue secGroup = null;
            try {
                secGroup = delegator.findOne("SecurityGroup", UtilMisc.toMap("groupId", securityGroup), true);
            } catch (GenericEntityException e) {
                Debug.logError(e, e.getMessage(), module);
            }

            // add it to the user if it exists
            if (secGroup != null) {
                Map<String, Serializable> createSecGrpMap = new HashMap<String, Serializable>();
                createSecGrpMap.put("userLoginId", userLoginId);
                createSecGrpMap.put("groupId", securityGroup);
                createSecGrpMap.put("fromDate", now);
                createSecGrpMap.put("userLogin", system);

                Map<String, Object> createSecGrpResult;
                try {
                    createSecGrpResult = dispatcher.runSync("addUserLoginToSecurityGroup", createSecGrpMap);
                } catch (GenericServiceException e) {
                    throw new AuthenticatorException(e.getMessage(), e);
                }
                if (ServiceUtil.isError(createSecGrpResult)) {
                    throw new AuthenticatorException(ServiceUtil.getErrorMessage(createSecGrpResult));
                }
            }
        }
        return userLoginId;
    }

    private void updateUser(Map<String, Object> userMap, GenericValue system, GenericValue userLogin) throws AuthenticatorException {
        // TODO implement me
    }

    /**
     * Updates a user's password.
     *
     * @param username    User's username
     * @param password    User's current password
     * @param newPassword User's new password
     * @throws org.apache.ofbiz.common.authentication.api.AuthenticatorException
     *          when update password fails
     */
    public void updatePassword(String username, String password, String newPassword) throws AuthenticatorException {
        Debug.logInfo("Calling GitHub:updatePassword() - ignored!!!", module);
    }

    /**
     * Weight of this authenticator (lower weights are run first)
     *
     * @return the weight of this Authenicator
     */
    public float getWeight() {
        return 1;
    }

    /**
     * Is the user synchronzied back to OFBiz
     *
     * @return true if the user record is copied to the OFB database
     */
    public boolean isUserSynchronized() {
        return true;
    }

    /**
     * Is this expected to be the only authenticator, if so errors will be thrown when users cannot be found
     *
     * @return true if this is expected to be the only Authenticator
     */
    public boolean isSingleAuthenticator() {
        return false;
    }

    /**
     * Flag to test if this Authenticator is enabled
     *
     * @return true if the Authenticator is enabled
     */
    public boolean isEnabled() {
        return "true".equalsIgnoreCase(UtilProperties.getPropertyValue(props, "github.authenticator.enabled", "true"));
    }

    public static Map<String, Object> getUserInfo(HttpGet httpGet, String accessToken, String tokenType, Locale locale) throws AuthenticatorException {
        JSON userInfo = null;
        httpGet.setConfig(PassportUtil.StandardRequestConfig);
        CloseableHttpClient jsonClient = HttpClients.custom().build();
        httpGet.setHeader(PassportUtil.AUTHORIZATION_HEADER, tokenType + " " + accessToken);
        httpGet.setHeader(PassportUtil.ACCEPT_HEADER, "application/json");
        CloseableHttpResponse getResponse = null;
		try {
			getResponse = jsonClient.execute(httpGet);
            String responseString = new BasicResponseHandler().handleResponse(getResponse);
	        if (getResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
	            // Debug.logInfo("Json Response from GitHub: " + responseString, module);
	            userInfo = JSON.from(responseString);
	        } else {
	            String errMsg = UtilProperties.getMessage(resource, "GetOAuth2AccessTokenError", UtilMisc.toMap("error", responseString), locale);
	            throw new AuthenticatorException(errMsg);
	        }
		} catch (ClientProtocolException e) {
            throw new AuthenticatorException(e.getMessage());
		} catch (IOException e) {
            throw new AuthenticatorException(e.getMessage());
		} finally {
			if (getResponse != null) {
	            try {
					getResponse.close();
				} catch (IOException e) {
					// do nothing
				}
			}
		}
        JSONToMap jsonMap = new JSONToMap();
        Map<String, Object> userMap;
        try {
            userMap = jsonMap.convert(userInfo);
        } catch (ConversionException e) {
            throw new AuthenticatorException(e.getMessage());
        }
        return userMap;
    }
}
