﻿using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage;
using Windows.Storage.Streams;

namespace Eve.Core
{
    public class LocalCacheService
    {
        static AsyncLock _asyncLock = new AsyncLock();

        static HashAlgorithmProvider _md5 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);

        public async Task SaveByKeyAsync(string key, string content)
        {
            using (await _asyncLock.LockAsync())
            {
                var fileName = "cache_" + key;

                var file = await ApplicationData.Current.LocalCacheFolder.CreateFileAsync(fileName,
                    CreationCollisionOption.ReplaceExisting);
                //var file =
                //    await
                //        FileSystem.Current.LocalStorage.CreateFileAsync(fileName,
                // CreationCollisionOption.ReplaceExisting);

                //var buffer = Windows.Security.Cryptography.CryptographicBuffer.ConvertStringToBinary(content, Windows.Security.Cryptography.BinaryStringEncoding.Utf8);

                //await Windows.Storage.FileIO.WriteBufferAsync(file, buffer);

                await FileIO.WriteTextAsync(file, content);

                //using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
                //{
                //    using (var dataWriter = new Windows.Storage.Streams.DataWriter(fileStream))
                //    {
                //        dataWriter.WriteString(content);
                //    }
                //}
            }
        }

        public async Task<string> LoadByKeyAsync(string key)
        {
            using (await _asyncLock.LockAsync())
            {
                var fileName = "cache_" + key;

                var existsFile = await ApplicationData.Current.LocalCacheFolder.TryGetItemAsync(fileName);

                //var existsFile = await FileSystem.Current.LocalStorage.CheckExistsAsync(fileName);

                if (existsFile != null)
                {
                    using (var stream = (await ((StorageFile)existsFile).OpenStreamForReadAsync()))
                    {
                        using (var dataReader = new StreamReader(stream, Encoding.UTF8))
                        {
                            var res = await dataReader.ReadToEndAsync();

                            return res;
                        }
                    }
                }

                return null;
            }
        }

        public Task<string> LoadAsync(string id)
        {
            var key = GetKey(id);

            return LoadByKeyAsync(key);
        }

        public Task SaveAsync(string id, string content)
        {
            var key = GetKey(id);

            return SaveByKeyAsync(key, content);
        }


        public static string GetKey(string id)
        {
            IBuffer buff = CryptographicBuffer.ConvertStringToBinary(id, BinaryStringEncoding.Utf8);
            var md5Buff = _md5.HashData(buff);
            var res = CryptographicBuffer.EncodeToHexString(md5Buff);
            return res;
        }
    }
}