using System;
using System.IO;
using System.IO.Abstractions;
using System.Text;
using System.Xml.Serialization;

namespace Valg.EVA.Skanning.UserInterfaceElements.UserSettings
{
    public class UserSettingsProvider : IUserSettingsProvider
    {
        private const string evaScanningFolder = @"Valgdirektoratet\EVA Skanning";
        private readonly IFileSystem fileSystem;
        private const string userSettingFileName = "UserSettings.xml";
        private const int userSettingVersion = 2;
        private UserSettings userSettings;

        public UserSettingsProvider(IFileSystem fileSystem)
        {
            this.fileSystem = fileSystem;
        }

        public UserSettings GetUserSettings()
        {
            if (userSettings == null)
            {
                var directory = GetUserSettingsDirectory();
                if (!directory.Exists)
                    SaveUserSettings(GetDefaultUserSettings());

                var userSettingsFile = GetUserSettingsFile();
                if (!userSettingsFile.Exists)
                    SaveUserSettings(GetDefaultUserSettings());

                var xml = fileSystem.File.ReadAllText(userSettingsFile.FullName);

                var serialiser = new XmlSerializer(typeof(UserSettings));
                userSettings = (UserSettings)serialiser.Deserialize(new StringReader(xml));

                if (userSettings.Version < userSettingVersion)
                {
                    userSettings = GetDefaultUserSettings();
                    fileSystem.File.Delete(userSettingsFile.FullName);
                    SaveUserSettings(userSettings);
                }
            }

            return userSettings;
        }

        private static UserSettings GetDefaultUserSettings()
        {
            return new UserSettings { Version = userSettingVersion, Language = "nb-NO", ShowVerifyNavigationTip = true, ShowBallotCompleteTip = true, ShowBlankBallotInformation = true, ShowUnknownBallotInformation = true };
        }

        public void SaveUserSettings(UserSettings updatedUserSettings)
        {
            userSettings = updatedUserSettings;

            var serialiser = new XmlSerializer(typeof(UserSettings));

            var underlyingBuilder = new StringBuilder();
            serialiser.Serialize(new StringWriter(underlyingBuilder), updatedUserSettings);

            var directory = GetUserSettingsDirectory();
            if (!directory.Exists)
                directory.Create();

            var file = GetUserSettingsFile();
            if (file.Exists)
                file.Delete();

            using (var streamWriter = file.CreateText())
            {
                streamWriter.WriteLine(underlyingBuilder);
                streamWriter.Flush();
                streamWriter.Close();
            }
        }

        public void ResetUserSettings()
        {
            var file = GetUserSettingsFile();
            
            if (file.Exists)
                file.Delete();

            userSettings = null;
        }

        private DirectoryInfoBase GetUserSettingsDirectory()
        {
            return fileSystem.DirectoryInfo.FromDirectoryName(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), evaScanningFolder));
        }

        private FileInfoBase GetUserSettingsFile()
        {
            return fileSystem.FileInfo.FromFileName(String.Format(@"{0}\{1}", GetUserSettingsDirectory().FullName, userSettingFileName));
        }
    }
}
