using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using BankTV.Consts;
using BankTV.Logger;
using BankTV.Exceptions;
using System.Windows;
using System.Xml;
using System.Net;
using BankTV.Config;
using System.Xml.Serialization;
using BankTV.Model;

namespace BankTV.Helpers.Config
{
    class XmlConfigHelper
    {

        private static configuration GetConfigObject()
        {
            try 
            {
                XmlSerializer serializer = new XmlSerializer(typeof(configuration));
                string appConfigFolder = GlobalHelper.GetUserAppDataFolder();
                if (String.IsNullOrEmpty(appConfigFolder))
                {
                    throw new AppNotInitiatedException("Unable to get app config folder.");
                }   //if
                string appConfigFile = System.IO.Path.Combine(appConfigFolder, GlobalConsts.APP_CONFIG_FILE);
                if (!File.Exists(appConfigFile))
                {
                    throw new AppNotInitiatedException("Unable to get app config folder.");
                }   //if
                TextReader reader = new StreamReader(appConfigFile);
                try
                {
                    return (configuration)serializer.Deserialize(reader);                    
                }   //try
                finally
                {
                    reader.Close();
                }   //finally
            }   //try
            catch (AppNotInitiatedException)
            {
                throw;
            }   //catch
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                MyLogger.Log(ex.GetBaseException());
                return null;
            }   //catch
        }

        private static configuration GetConfigObject(String fileName)
        {
            if (String.IsNullOrWhiteSpace(fileName))
            {
                fileName = GlobalConsts.APP_CONFIG_FILE;
            }   //if
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(configuration));
                string appConfigFolder = GlobalHelper.GetUserAppDataFolder();
                if (String.IsNullOrEmpty(appConfigFolder))
                {
                    throw new AppNotInitiatedException("Unable to get app config folder.");
                }   //if
                string appConfigFile = System.IO.Path.Combine(appConfigFolder, fileName);
                if (!File.Exists(appConfigFile))
                {
                    appConfigFile = System.IO.Path.Combine(appConfigFolder, GlobalConsts.APP_CONFIG_FILE);
                    if (!File.Exists(appConfigFile))
                    {
                        throw new AppNotInitiatedException("Unable to get app config folder.");
                    }   //if
                }   //if
                TextReader reader = new StreamReader(appConfigFile);
                try
                {
                    return (configuration)serializer.Deserialize(reader);
                }   //try
                finally
                {
                    reader.Close();
                }   //finally
            }   //try
            catch (AppNotInitiatedException)
            {
                throw;
            }   //catch
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                MyLogger.Log(ex.GetBaseException());
                return null;
            }   //catch
        }

        public static int GetCurrentVersion()
        {
            try
            {
                configuration xmlConfig = XmlConfigHelper.GetConfigObject();
                return xmlConfig.version;
            }
            catch (AppNotInitiatedException)
            {
                return 0;
            }   //catch
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                throw;
            }
        }

        private static Screen GetSingleScreen(configurationScreen configurationScreen)
        {
            try
            {
                if (configurationScreen == null)
                {
                    return null;
                }   //if
                int id;
                int ordering;
                Screen screen = new Screen();
                screen.Abbr = configurationScreen.abbr;
                screen.Type = ModelHelper.StringToScreenType(configurationScreen.type);
                screen.Content = configurationScreen.content;
                screen.FileName = configurationScreen.file_name;
                bool parseSuccess = int.TryParse(configurationScreen.id, out id);
                if (parseSuccess)
                {
                    screen.Id = id;
                }   //if
                else
                {
                    screen.Id = -1;
                }   //else
                parseSuccess = int.TryParse(configurationScreen.ordering, out ordering);
                if (parseSuccess)
                {
                    screen.Ordering = ordering;
                }   //if
                else
                {
                    screen.Ordering = -1;
                }   //else
                screen.Title = configurationScreen.title;
                return screen;
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                return null;
            }   //catch

        }

        private static List<Screen> GetScreensList(configuration config)
        {
            try
            {
                if (config == null)
                {
                    throw new AppNotInitiatedException("Unable to get app configuration.");
                }   //if
                configurationScreen[] configurationScreens = config.screen;
                if (configurationScreens == null)
                {
                    throw new AppNotInitiatedException("No screens configured.");
                }   //if
                if (configurationScreens.Count() == 0)
                {
                    throw new AppNotInitiatedException("No screens configured.");
                }   //if
                List<Screen> screens = new List<Screen>();
                foreach (configurationScreen configurationScreen in configurationScreens)
                {
                    Screen screen = XmlConfigHelper.GetSingleScreen(configurationScreen);
                    if (screen != null)
                    {
                        screens.Add(screen);
                    }   //if
                }   //for
                return screens;
            }   //try
            catch (AppNotInitiatedException)
            {
                throw;
            }   //catch
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                return null;
            }   //catch
        }

        public static List<Screen> GetScreensList()
        {
            try
            {
                configuration config = XmlConfigHelper.GetConfigObject();
                if (config == null)
                {
                    throw new AppNotInitiatedException("Unable to get app configuration.");
                }   //if
                return XmlConfigHelper.GetScreensList(config);
            }   //try
            catch (AppNotInitiatedException)
            {
                throw;
            }   //catch
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                return null;
            }   //catch
        }

        public static List<Screen> GetScreensList(String fileName)
        {
            try
            {
                configuration config = XmlConfigHelper.GetConfigObject(fileName);
                if (config == null)
                {
                    throw new AppNotInitiatedException("Unable to get app configuration.");
                }   //if
                return XmlConfigHelper.GetScreensList(config);
            }   //try
            catch (AppNotInitiatedException)
            {
                throw;
            }   //catch
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                return null;
            }   //catch
        }

    }

}
