/*
 * Copyright 2013 gitblit.com.
 *
 * Licensed 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 com.gitblit.auth;

import java.io.File;
import java.math.BigInteger;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.Constants.AccountType;
import com.gitblit.Constants.Role;
import com.gitblit.Constants.AuthenticationType;
import com.gitblit.IStoredSettings;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.manager.IUserManager;
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.DeepCopier;
import com.gitblit.utils.StringUtils;

public abstract class AuthenticationProvider {

	public static NullProvider NULL_PROVIDER = new NullProvider();

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    protected final String serviceName;

	protected File baseFolder;

	protected IStoredSettings settings;

	protected IRuntimeManager runtimeManager;

	protected IUserManager userManager;

	protected AuthenticationProvider(String serviceName) {
		this.serviceName = serviceName;
	}

	/**
	 * Returns the file object for the specified configuration key.
	 *
	 * @return the file
	 */
	public File getFileOrFolder(String key, String defaultFileOrFolder) {
		return runtimeManager.getFileOrFolder(key, defaultFileOrFolder);
	}

	public final void setup(IRuntimeManager runtimeManager, IUserManager userManager) {
		this.baseFolder = runtimeManager.getBaseFolder();
		this.settings = runtimeManager.getSettings();
		this.runtimeManager = runtimeManager;
		this.userManager = userManager;
		setup();
	}

	public String getServiceName() {
		return serviceName;
	}

	public abstract AuthenticationType getAuthenticationType();

	protected void setCookie(UserModel user, char [] password) {
		// create a user cookie
		if (StringUtils.isEmpty(user.cookie) && !ArrayUtils.isEmpty(password)) {
			user.cookie = StringUtils.getSHA1(user.username + new String(password));
		}
	}

	protected void updateUser(UserModel userModel) {
		final UserModel userLocalDB = userManager.getUserModel(userModel.getName());

		// Establish the checksum of the current version of the user
		final BigInteger userCurrentCheck = DeepCopier.checksum(userModel);

		// Establish the checksum of the stored version of the user
		final BigInteger userLocalDBcheck = DeepCopier.checksum(userLocalDB);

		// Compare the checksums
		if (!userCurrentCheck.equals(userLocalDBcheck)) {
			// If mismatch, save the new instance.
			userManager.updateUserModel(userModel);
		}
	}

	protected void updateTeam(TeamModel teamModel) {
		final TeamModel teamLocalDB = userManager.getTeamModel(teamModel.name);

		// Establish the checksum of the current version of the team
		final BigInteger teamCurrentCheck = DeepCopier.checksum(teamModel);

		// Establish the checksum of the stored version of the team
		final BigInteger teamLocalDBcheck = DeepCopier.checksum(teamLocalDB);

		// Compare the checksums
		if (!teamCurrentCheck.equals(teamLocalDBcheck)) {
			// If mismatch, save the new instance.
			userManager.updateTeamModel(teamModel);
		}
	}

	public abstract void setup();

	public abstract void stop();

	/**
	 * Used to handle requests for requests for pages requiring authentication.
	 * This allows authentication to occur based on the contents of the request
	 * itself.
	 *
	 * @param httpRequest
	 * @return
	 */
	public abstract UserModel authenticate(HttpServletRequest httpRequest);

	/**
	 * Used to authentication user/password credentials, both for login form
	 * and HTTP Basic authentication processing.
	 *
	 * @param username
	 * @param password
	 * @return
	 */
	public abstract UserModel authenticate(String username, char[] password);

	public abstract AccountType getAccountType();

	/**
	 * Returns true if the users's credentials can be changed.
	 *
	 * @return true if the authentication provider supports credential changes
	 * @since 1.0.0
	 */
	public abstract boolean supportsCredentialChanges();

	/**
	 * Returns true if the user's display name can be changed.
	 *
	 * @param user
	 * @return true if the authentication provider supports display name changes
	 */
	public abstract boolean supportsDisplayNameChanges();

	/**
	 * Returns true if the user's email address can be changed.
	 *
	 * @param user
	 * @return true if the authentication provider supports email address changes
	 */
	public abstract boolean supportsEmailAddressChanges();

	/**
	 * Returns true if the user's team memberships can be changed.
	 *
	 * @param user
	 * @return true if the authentication provider supports team membership changes
	 */
	public abstract boolean supportsTeamMembershipChanges();

	/**
	 * Returns true if the user's role can be changed.
	 *
	 * @param user
	 * @param role
	 * @return true if the user's role can be changed
	 */
	public abstract boolean supportsRoleChanges(UserModel user, Role role);

	/**
	 * Returns true if the team's role can be changed.
	 *
	 * @param user
	 * @param role
	 * @return true if the team's role can be changed
	 */
	public abstract boolean supportsRoleChanges(TeamModel team, Role role);

    @Override
    public String toString() {
    	return getServiceName() + " (" + getClass().getName() + ")";
    }

    public abstract static class UsernamePasswordAuthenticationProvider extends AuthenticationProvider {
    	protected UsernamePasswordAuthenticationProvider(String serviceName) {
    		super(serviceName);
    	}

		@Override
		public UserModel authenticate(HttpServletRequest httpRequest) {
			return null;
		}

		@Override
		public AuthenticationType getAuthenticationType() {
			return AuthenticationType.CREDENTIALS;
		}

    	@Override
		public void stop() {

		}
    }

    public static class NullProvider extends AuthenticationProvider {

		protected NullProvider() {
			super("NULL");
		}

		@Override
		public void setup() {

		}

		@Override
		public void stop() {

		}

		@Override
		public UserModel authenticate(HttpServletRequest httpRequest) {
			return null;
		}

		@Override
		public UserModel authenticate(String username, char[] password) {
			return null;
		}

		@Override
		public AccountType getAccountType() {
			return AccountType.LOCAL;
		}

		@Override
		public AuthenticationType getAuthenticationType() {
			return null;
		}

		@Override
		public boolean supportsCredentialChanges() {
			return true;
		}

		@Override
		public boolean supportsDisplayNameChanges() {
			return true;
		}

		@Override
		public boolean supportsEmailAddressChanges() {
			return true;
		}

		@Override
		public boolean supportsTeamMembershipChanges() {
			return true;
		}

		@Override
		public boolean supportsRoleChanges(UserModel user, Role role) {
			return true;
		}

		@Override
		public boolean supportsRoleChanges(TeamModel team, Role role) {
			return true;
		}

    }
}
