using System;
using System.Collections.Generic;

namespace MOH_CRA_XCRMS_Service.Common
{
    internal static class SymetricEncrypting
    {
        public static Dictionary<string, SymetricEncryptionKey> _symetricEncryptionKeys = new Dictionary<string, SymetricEncryptionKey>();

        public static byte[] GetSymetricEncryptionKey_SubcontractId(string subContractId, string keyExchangeSubcontractId,
                     string organizationUnit, string unitName, out long keyId)
        {
            byte[] symetricKey;
            var now = DateTime.Now;

            if (!_symetricEncryptionKeys.ContainsKey(keyExchangeSubcontractId) ||
                _symetricEncryptionKeys[keyExchangeSubcontractId].ExpirationDate <= now)
            {
                var keyExchange = new KeyExchange();

                keyExchange.GenerateKeyPair();

                var signingCertificate = Helpers.GetCertificate(subContractId + "_KeyExchangeSubcontractId", organizationUnit, unitName);
                keyExchange.PerformExchange(keyExchangeSubcontractId, signingCertificate);

                symetricKey = keyExchange.CalculateSecureSymetricKey();
                //should be stored somewhere to use for encryption and decryption until next key exchange (persumably once per day)
                if (!_symetricEncryptionKeys.ContainsKey(keyExchangeSubcontractId))
                {
                    _symetricEncryptionKeys.Add(keyExchangeSubcontractId, new SymetricEncryptionKey
                    {
                        ExpirationDate = now.AddHours(22),
                        KeyExchange = symetricKey,
                        KeyId = keyExchange.KeyId
                    });
                }
                else
                {
                    _symetricEncryptionKeys[keyExchangeSubcontractId].KeyId = keyExchange.KeyId;
                    _symetricEncryptionKeys[keyExchangeSubcontractId].KeyExchange = symetricKey;
                    _symetricEncryptionKeys[keyExchangeSubcontractId].ExpirationDate = now.AddHours(22);
                }
                keyId = keyExchange.KeyId;
            }
            else
            {
                keyId = _symetricEncryptionKeys[keyExchangeSubcontractId].KeyId;
                symetricKey = _symetricEncryptionKeys[keyExchangeSubcontractId].KeyExchange;
            }
            return symetricKey;
        }
    }

    internal class SymetricEncryptionKey
    {
        internal byte[] KeyExchange { get; set; }
        internal long KeyId { get; set; }
        internal DateTime ExpirationDate { get; set; }
    }
}