using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Javax.Crypto;
using Javax.Crypto.Spec;
using TINK.Droid.Model.Device;
using TINK.Model.Device;
using Xamarin.Forms;

[assembly: Dependency(typeof(TINK.Droid.Model.Device.DroidCipher))]
namespace TINK.Droid.Model.Device
{
    public class DroidCipher : ICipher
    {
        /// <summary> Encrypt data.</summary>
        /// <param name="key">Key to encrypt data.</param>
        /// <param name="clear">Data to entrycpt.</param>
        /// <returns></returns>
        public byte[] Encrypt(byte[] key, byte[] clear)
        {
            SecretKeySpec skeySpec = new SecretKeySpec(key, 0, 24, "AES");
            Cipher cipher = Cipher.GetInstance("AES/ECB/NoPadding");
            cipher.Init(CipherMode.EncryptMode, skeySpec);
            return cipher.DoFinal(clear);
        }

        /// <summary> Decrypt data. </summary>
        /// <param name="key">Key to decrypt data with.</param>
        /// <param name="encrypted">Encrpyted data to decrypt.</param>
        /// <returns>Decrypted data.</returns>
        public byte[] Decrypt(byte[] key, byte[] encrypted)
        {
            TestDecrypt();

            SecretKeySpec skeySpec = new SecretKeySpec(key, 0, 24, "AES");
            Cipher cipher = Cipher.GetInstance("AES/ECB/NoPadding");
            cipher.Init(CipherMode.DecryptMode, skeySpec);
            return cipher.DoFinal(encrypted);
        }

        public void TestDecrypt()
        {
            byte[] decyptedText;
            
            var encryptedText = (new sbyte[] { 50, 51, -40, 64, 42, 82, 97, -24, 20, -39, -15, 126, 119, -110, 47, -18 }).Select(x => (byte)x).ToArray();
            
            var key = (new sbyte[] { -6, 53, 29, -112, 7, -83, -41, -7, 30, 45, -13, -2, -108, -29, -90, 71, 15, -74, -76, 32, 0, 0, 0, 0 }).Select(x => (byte)x).ToArray();

            var expecedResult = (new sbyte[] { 19, -66, 55, 18, -106, -92, 70, -40, 117, -87, -19, 124, 19, 54, -18, -82 }).Select(x => (byte)x).ToArray();

            SecretKeySpec skeySpec = new SecretKeySpec(key, 0, 24, "AES");
            Cipher cipher = Cipher.GetInstance("AES/ECB/NoPadding");
            cipher.Init(CipherMode.DecryptMode, skeySpec);
            decyptedText = cipher.DoFinal(encryptedText);

            if (!expecedResult.SequenceEqual(decyptedText))
            {
                throw new System.Exception("Decrypted text does not match expectation.");
            }
        }
    }
}