using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Reflection;
using TreeksLicensingLibrary;

/// <summary>
/// Contains functions to work with TLL
/// </summary>
/// <remarks></remarks>
public class TLLInterface
{

    //Just paste from toolbox
	private const string MyPublicKey = "Put your PUBLIC key XML here.";
    
	private const string MyLicenseXML = "Put your license from us here";

	private LicenseVerification verification = new LicenseVerification(MyPublicKey);
	/// <summary>
	/// Call this function to verify user's license. Optionally supply string and License object to get more information (error message, license details)
	/// </summary>
	/// <param name="ErrorMessage">Gives you more information if license validation failed</param>
	/// <param name="LicenseObject">Contains license details</param>
	/// <returns>Bool: True if license was successfully verified</returns>
	/// <remarks></remarks>
	public bool IsLicenseValid(ref string ErrorMessage, ref TreeksLicensingLibrary.License LicenseObject)
	{

		string LicenseFilePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\registration.lic";

		if (ValidateLicensingLibrary()) {
			if (File.Exists(LicenseFilePath)) {
				if (verification.VerifyLicenseFile(LicenseFilePath, ref ErrorMessage, ref LicenseObject)) {
					return true;
				} else {
					return false;
				}
			} else {
				ErrorMessage = "License file not present.";
				return false;
			}
		} else {
			ErrorMessage = "Library integrity check failed.";
			return false;
		}
	}

	/// <summary>
	/// Return actual hardware ID
	/// </summary>
	/// <returns>String: Actual hardware ID</returns>
	/// <remarks></remarks>
	public string GetAactualHardwareID()
	{
		return HardwareID.ActualHardwareID;
	}

	/// <summary>
	/// Validates if TLL was not modified by unathorized user
	/// </summary>
	/// <returns>Bool: True if file was not modified</returns>
	/// <remarks></remarks>
	private bool ValidateLicensingLibrary()
	{

		SHA1 sha = new SHA1();
		string path = LibraryDLLPath();

		string current_hash = sha.hashOfFile(path);
		string valid_hash = "7e4b6c0c073853205dbb92bf0798e977a36dbf75";

		if (valid_hash == current_hash) {
			return true;
		} else {
			return false;
		}

	}

	/// <summary>
	/// Disables TLL demo message
	/// </summary>
	/// <remarks></remarks>
	private void SetLicenseInformation()
	{
		TreeksLicensingLibrary.DeveloperLicense.LicenseXML = MyLicenseXML;
	}

	/// <summary>
	/// Returns path of TLL to verify integrity
	/// </summary>
	/// <returns>String: Treek's Licensing Library DLL path</returns>
	/// <remarks></remarks>
	private string LibraryDLLPath()
	{

		string dirpath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		if (!dirpath.EndsWith("\\"))
			dirpath += "\\";

		string path = dirpath + "TreeksLicensingLibrary.dll";

		return path;

	}

}

/// <summary>
/// Contains interface to work with SHA1
/// </summary>
/// <remarks></remarks>
public class SHA1 
{

	/// <summary>
	/// Returns SHA1 hash of file
	/// </summary>
	/// <param name="fileToHash">Filesystem path to hashed file</param>
	/// <returns>String</returns>
	/// <remarks></remarks>
	public string hashOfFile(string fileToHash)
	{
		FileStream rdr = default(FileStream);
		SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
		byte[] bytes = null;
		string rtn = "";
		if (File.Exists(fileToHash)) {
			rdr = new FileStream(fileToHash, FileMode.Open, FileAccess.Read);
			bytes = sha.ComputeHash(rdr);
			rtn = ByteArrayToString(bytes);
		}
		return rtn;
	}

	/// <summary>
	/// Returns SHA1 hash of string
	/// </summary>
	/// <param name="stringToHash">String to be hashed</param>
	/// <returns>String</returns>
	/// <remarks></remarks>
	public string hashOfString(string stringToHash)
	{
		SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
		byte[] bytesToHash = System.Text.Encoding.ASCII.GetBytes(stringToHash);
		bytesToHash = sha.ComputeHash(bytesToHash);
		string strResult = "";
		foreach (byte b in bytesToHash) {
			strResult += b.ToString("x2");
		}
		return strResult;
	}

	private string ByteArrayToString(byte[] arrInput)
	{
		System.Text.StringBuilder sb = new System.Text.StringBuilder(arrInput.Length * 2);
		for (int i = 0; i <= arrInput.Length - 1; i++) {
			sb.Append(arrInput[i].ToString("X2"));
		}

		return sb.ToString().ToLower();
	}


}

