using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BankTVUpdater.Logger;
using BankTVUpdater.AppUpdaterService;
using BankTVUpdater.Exceptions;
using System.Net;

namespace BankTVUpdater.Helpers.Service
{
    class ServiceConfiguration
    {
        private static ServiceConfiguration instance;

        private eBankTvIntegrationService updateService;

        private ServiceConfiguration() 
        {
            
        }

        public static ServiceConfiguration Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ServiceConfiguration();
                }
                return instance;
            }
        }

        private eBankTvIntegrationService GetUpdateService()
        {
            try
            {
                if (this.updateService == null)
                {
                    this.updateService = new eBankTvIntegrationService();
                    if (!this.checkWebServiceAvailability(this.updateService.Url))
                    {
                        throw new Exception("Unable to connect to remote server.");
                    }   //if
                }
                return this.updateService;
            }   //try
            catch (Exception ex)
            {
                MyLogger.Log(ex);
            }   //catch
            return null;
        }

        private bool checkWebServiceAvailability(string url)
        {
            if (String.IsNullOrEmpty(url))
            {
                return false;
            }   //if
            try
            {
                var myRequest = (HttpWebRequest)WebRequest.Create(url);
                var response = (HttpWebResponse)myRequest.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    return true;
                }   //if
                return false;
            }
            catch (Exception ex)
            {
                MyLogger.Log(ex);
                return false;
            }
        }

        public string CallGetAppConfiguration()
        {
            this.LogStartUpdateOperation("getAppConfiguration");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getAppConfiguration", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                string result = service.getAppConfiguration(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getAppConfiguration");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getAppConfiguration", ex);
                throw;
            }   //catch
        }

        public Departments CallGetDepartments()
        {
            this.LogStartUpdateOperation("getDepartments");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getDepartments", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                Departments result = service.getDepartments(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getDepartments");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getDepartments", ex);
                throw;
            }   //catch
        }

        public string CallGetAppForDepartmentConfiguration(string param)
        {
            if (String.IsNullOrWhiteSpace(param))
            {
                return this.CallGetAppConfiguration();
            }   //if
            this.LogStartUpdateOperation("getAppForDepartmentConfiguration");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getAppForDepartmentConfiguration", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                string result = service.getAppConfigurationForDepartment(param, TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getAppForDepartmentConfiguration");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getAppForDepartmentConfiguration", ex);
                throw;
            }   //catch
        }

        public bool CallAppUpdaterNeedsUpdate(int currentUpdaterVersion)
        {
            this.LogStartUpdateOperation("appUpdaterNeedsUpdate");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("appUpdaterNeedsUpdate", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                bool result = service.appUpdaterNeedsUpdate(currentUpdaterVersion, TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("appUpdaterNeedsUpdate");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("appUpdaterNeedsUpdate", ex);
                throw;
            }   //catch
        }

        public bool CallAppNeedsUpdate(int currentVersion)
        {
            this.LogStartUpdateOperation("appNeedsUpdate");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("appNeedsUpdate", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                bool result = service.appNeedsUpdate(currentVersion, TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("appNeedsUpdate");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("appNeedsUpdate", ex);
                throw;
            }   //catch
        }

        public Files CallGetImageFiles()
        {
            this.LogStartUpdateOperation("getImageFiles");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getImageFiles", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                Files result = service.getImageFiles(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getImageFiles");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getImageFiles", ex);
                throw;
            }   //catch
        }

        public Files CallGetFlashFiles()
        {
            this.LogStartUpdateOperation("getFlashFiles");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getFlashFiles", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                Files result = service.getFlashFiles(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getFlashFiles");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getFlashFiles", ex);
                throw;
            }   //catch
        }

        public Files CallGetVideoFiles()
        {
            this.LogStartUpdateOperation("getVideoFiles");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getVideoFiles", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                Files result = service.getVideoFiles(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getVideoFiles");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getVideoFiles", ex);
                throw;
            }   //catch
        }

        public News CallGetNews()
        {
            this.LogStartUpdateOperation("getNews");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getNews", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                News result = service.getNews(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getNews");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getNews", ex);
                throw;
            }   //catch
        }

        public CurrencyItemsList CallGetCurrencies()
        {
            this.LogStartUpdateOperation("getCurrencies");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getCurrencies", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                CurrencyItemsList result = service.getCurrencies(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getCurrencies");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getCurrencies", ex);
                throw;
            }   //catch
        }

        public WeatherIcons CallGetWeatherIcons()
        {
            this.LogStartUpdateOperation("getWeatherIcons");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getWeatherIcons", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                WeatherIcons result = service.getWeatherIcons(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getWeatherIcons");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getWeatherIcons", ex);
                throw;
            }   //catch
        }

        public string CallGetCurrenciesConfigFile()
        {
            this.LogStartUpdateOperation("getCurrenciesConfigFile");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getCurrenciesConfigFile", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                string result = service.getCurrenciesConfigFile(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getCurrenciesConfigFile");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getCurrenciesConfigFile", ex);
                throw;
            }   //catch
        }

        public BankTVUpdater.AppUpdaterService.BottomBarNews CallGetBottomBarNews()
        {
            this.LogStartUpdateOperation("getBottomBarNews");
            eBankTvIntegrationService service = this.GetUpdateService();
            if (service == null)
            {
                this.LogErrorUpdateOperation("getBottomBarNews", "Unable to connect to update server");
                throw new UpdaterConnectionException();
            }
            try
            {
                BankTVUpdater.AppUpdaterService.BottomBarNews result = service.getBottomBarNews(TokenHelper.GenerateAuthToken());
                this.LogFinishUpdateOperation("getBottomBarNews");
                return result;
            }
            catch (Exception ex)
            {
                this.LogErrorUpdateOperation("getBottomBarNews", ex);
                throw;
            }   //catch
        }

        private void LogStartUpdateOperation(string operation)
        {
            MyLogger.Log(String.Format("Update operation {0} started.", operation));
        }

        private void LogFinishUpdateOperation(string operation)
        {
            MyLogger.Log(String.Format("Update operation {0} finished.", operation));
        }

        private void LogErrorUpdateOperation(string operation, Exception ex)
        {
            MyLogger.Log(String.Format("Update operation {0} - error occurred.", operation), MyLogger.LogLevel.Error);
            if (ex != null)
            {
                MyLogger.Log(ex);
            }   //if
        }

        private void LogErrorUpdateOperation(string operation, string error)
        {
            MyLogger.Log(String.Format("Update operation {0} - error occurred: {1}", operation, error), MyLogger.LogLevel.Error);
        }

    }

}
