package com.nifty.cloud.ncs.auth;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

/**
 * ニフクラサービスで使用するアクセスキー、およびシークレットキーを保持するクラスです。
 *
 */
public class Credentials
{
	private static final String ACCESSKEY_NAME = "accessKey";
	private static final String SECRETKEY_NAME = "secretKey";
	private static final String EXTENDED_HEADER_PREFIX = "extendedHeaderPrefix";
	private static final String AUTHORIZATION_HEADER_PREFIX = "authorizationHeaderPrefix";

	private static final String DEFAULT_EXTENDED_HEADER_PREFIX = "x-nifty";
	private static final String DEFAULT_AUTHORIZATION_HEADER_PREIX = "NIFTY";

	private final String accessKey;
	private final String secretKey;
	private String extendedHeaderPrefix;
	private String authorizationHeaderPrefix;


	/**
	 * 新しいCredentialsを構築します。
	 *
	 * @param file
	 *  アクセスキー、シークレットキーの情報を持つファイル
	 *
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws IllegalArgumentException
	 */
	public Credentials(File file) throws FileNotFoundException, IOException, IllegalArgumentException
	{
		if (file.exists() == false) {
			throw (new FileNotFoundException("File not found: " + file.getAbsolutePath()));
		}

		Properties properties = new Properties();
		properties.load(new FileInputStream(file));

		String propAccessKey = properties.getProperty(ACCESSKEY_NAME);
		if (propAccessKey == null) {
			throw (new IllegalArgumentException("The specified file [" + file.getAbsolutePath() + "] " + "does not contain the expected property " + "'" + ACCESSKEY_NAME + "'"));
		}
		else if (propAccessKey.isEmpty()) {
			throw (new IllegalArgumentException("The specified file [" + file.getAbsolutePath() + "] " + "contains the expected property " + "'" + ACCESSKEY_NAME + "', but the value is empty"));
		}

		String propSecretKey = properties.getProperty(SECRETKEY_NAME);
		if (properties.getProperty(SECRETKEY_NAME) == null) {
			throw (new IllegalArgumentException("The specified file [" + file.getAbsolutePath() + "] " + "does not contain the expected property " + "'" + SECRETKEY_NAME + "'"));
		}
		else if (propSecretKey.isEmpty()) {
			throw (new IllegalArgumentException("The specified file [" + file.getAbsolutePath() + "] " + "contains the expected property " + "'" + SECRETKEY_NAME + "', but the value is empty"));
		}

		this.accessKey = properties.getProperty(ACCESSKEY_NAME);
		this.secretKey = properties.getProperty(SECRETKEY_NAME);

		String propExtendedHeaderKey = properties.getProperty(EXTENDED_HEADER_PREFIX);
		if (propExtendedHeaderKey != null && propExtendedHeaderKey.isEmpty() == false) {
			this.extendedHeaderPrefix = propExtendedHeaderKey;
		} else {
			this.extendedHeaderPrefix = DEFAULT_EXTENDED_HEADER_PREFIX;
		}
		String propAuthorizationHeaderKey = properties.getProperty(AUTHORIZATION_HEADER_PREFIX);
		if (propAuthorizationHeaderKey != null && propAuthorizationHeaderKey.isEmpty() == false) {
			this.authorizationHeaderPrefix = propAuthorizationHeaderKey;
		} else {
			this.authorizationHeaderPrefix = DEFAULT_AUTHORIZATION_HEADER_PREIX;
		}
	}

	/**
	 * アクセスキー、シークレットキーを指定してCredentialsを構築します。
	 *
	 * @param accessKey
	 *  アクセスキー
	 * @param secretKey
	 *  シークレットキー
	 */
	public Credentials(String accessKey, String secretKey)
	{
		this(accessKey, secretKey, DEFAULT_EXTENDED_HEADER_PREFIX, DEFAULT_AUTHORIZATION_HEADER_PREIX);
	}

	/**
	 * アクセスキー、シークレットキー、HTTP拡張ヘッダの接頭辞、および認証文字列の接頭辞を指定してCredentialsを構築します。
	 *
	 * @param accessKey
	 *  アクセスキー
	 * @param secretKey
	 *  シークレットキー
	 * @param extendedHeaderPrefix
	 *  HTTP拡張ヘッダの接頭辞 (例： x-nifty-)
	 * @param authorizationHeaderPrefix
	 *   認証文字列の接頭辞 (例： NIFTY)
	 */
	public Credentials(String accessKey, String secretKey, String extendedHeaderPrefix, String authorizationHeaderPrefix)
	{
		if (accessKey == null || accessKey.isEmpty()) {
			throw (new IllegalArgumentException("The parameter " + ACCESSKEY_NAME + " must not be null or empty."));
		}

		if (secretKey == null || secretKey.isEmpty()) {
			throw (new IllegalArgumentException("The parameter " + SECRETKEY_NAME + " must not be null or empty."));
		}

		if (extendedHeaderPrefix == null || extendedHeaderPrefix.isEmpty()) {
			throw (new IllegalArgumentException("The parameter " + EXTENDED_HEADER_PREFIX + " must not be null or empty."));
		}

		if (authorizationHeaderPrefix == null || authorizationHeaderPrefix.isEmpty()) {
			throw (new IllegalArgumentException("The parameter " + DEFAULT_AUTHORIZATION_HEADER_PREIX + " must not be null or empty."));
		}

		this.accessKey = accessKey;
		this.secretKey = secretKey;
		this.extendedHeaderPrefix = extendedHeaderPrefix;
		this.authorizationHeaderPrefix = authorizationHeaderPrefix;
	}

	/**
	 * アクセスキーを取得します。
	 *
	 * @return
	 *  アクセスキー
	 */
	public String getAccessKey()
	{
		return (this.accessKey);
	}

	/**
	 * シークレットキーを取得します。
	 *
	 * @return
	 *  シークレットキー
	 */
	public String getSecretKey()
	{
		return (this.secretKey);
	}

	/**
	 * HTTP拡張ヘッダの接頭辞を設定します。
	 *
	 * @param extendedHeaderPrefix
	 *  HTTP拡張ヘッダの接頭辞
	 */
	public void setExtendedHeaderPrefix(String extendedHeaderPrefix)
	{
		this.extendedHeaderPrefix = extendedHeaderPrefix;
	}

	/**
	 * HTTP拡張ヘッダの接頭辞を取得します。
	 *
	 * @return
	 *  HTTP拡張ヘッダの接頭辞
	 */
	public String getExtendedHeaderPrefix()
	{
		return (this.extendedHeaderPrefix);
	}

	/**
	 * 認証文字列の接頭辞を設定します。
	 *
	 * @param authorizationHeaderPrefix
	 *  認証文字列の接頭辞
	 */
	public void setAuthorizationHeaderPrefix(String authorizationHeaderPrefix)
	{
		this.authorizationHeaderPrefix = authorizationHeaderPrefix;
	}

	/**
	 * 認証文字列の接頭辞を取得します。
	 *
	 * @return
	 *  認証文字列の接頭辞
	 */
	public String getAuthorizationHeaderPrefix()
	{
		return (this.authorizationHeaderPrefix);
	}
}
