package fr.xephi.authme.api;

import java.security.NoSuchAlgorithmException;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;

import cn.citycraft.AuthMe.AuthMe;
import cn.citycraft.AuthMe.Utils;
import cn.citycraft.AuthMe.cache.auth.PlayerAuth;
import cn.citycraft.AuthMe.cache.auth.PlayerCache;
import cn.citycraft.AuthMe.security.PasswordSecurity;
import cn.citycraft.AuthMe.settings.Settings;

public class NewAPI {

	public static final String newline = System.getProperty("line.separator");
	public static NewAPI singleton;
	public AuthMe plugin;

	public NewAPI(final AuthMe plugin) {
		this.plugin = plugin;
	}

	public NewAPI(final Server serv) {
		this.plugin = (AuthMe) serv.getPluginManager().getPlugin("AuthMe");
	}

	/**
	 * Hook into AuthMe
	 *
	 * @return AuthMe plugin
	 */
	public static NewAPI getInstance() {
		if (singleton != null) {
			return singleton;
		}
		final Plugin p = Bukkit.getServer().getPluginManager().getPlugin("AuthMe");
		if (p == null || !(p instanceof AuthMe)) {
			return null;
		}
		final AuthMe authme = (AuthMe) p;
		singleton = (new NewAPI(authme));
		return singleton;
	}

	/**
	 * @param String
	 *            playerName, String passwordToCheck
	 * @return true if the password is correct , false else
	 */
	public boolean checkPassword(final String playerName, final String passwordToCheck) {
		if (!isRegistered(playerName)) {
			return false;
		}
		final String player = playerName.toLowerCase();
		final PlayerAuth auth = plugin.database.getAuth(player);
		try {
			return PasswordSecurity.comparePasswordWithHash(passwordToCheck, auth.getHash(), playerName);
		} catch (final NoSuchAlgorithmException e) {
			return false;
		}
	}

	/**
	 * Force a player to login
	 *
	 * @param Player
	 *            player
	 */
	public void forceLogin(final Player player) {
		plugin.management.performLogin(player, "dontneed", true);
	}

	public Location getLastLocation(final Player player) {
		try {
			final PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName().toLowerCase());

			if (auth != null) {
				return new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ());
			} else {
				return null;
			}

		} catch (final NullPointerException ex) {
			return null;
		}
	}

	public AuthMe getPlugin() {
		return plugin;
	}

	/**
	 *
	 * @param player
	 * @return true if player is authenticate
	 */
	public boolean isAuthenticated(final Player player) {
		return PlayerCache.getInstance().isAuthenticated(player.getName());
	}

	/**
	 *
	 * @param player
	 * @return true if player is a npc
	 */
	public boolean isNPC(final Player player) {
		return Utils.isNPC(player);
	}

	/**
	 *
	 * @param playerName
	 * @return true if player is registered
	 */
	public boolean isRegistered(final String playerName) {
		final String player = playerName.toLowerCase();
		return plugin.database.isAuthAvailable(player);
	}

	/**
	 *
	 * @param player
	 * @return true if the player is unrestricted
	 */
	public boolean isUnrestricted(final Player player) {
		return Utils.isUnrestricted(player);
	}

	/**
	 * Register a player
	 *
	 * @param String
	 *            playerName, String password
	 * @return true if the player is register correctly
	 */
	public boolean registerPlayer(final String playerName, final String password) {
		try {
			final String name = playerName.toLowerCase();
			final String hash = PasswordSecurity.getHash(Settings.getPasswordHash, password, name);
			if (isRegistered(name)) {
				return false;
			}
			final PlayerAuth auth = new PlayerAuth(name, hash, "127.0.0.1", 0, "mc@mc.com", playerName);
			return plugin.database.saveAuth(auth);
		} catch (final NoSuchAlgorithmException ex) {
			return false;
		}
	}

}
