
// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2021 Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.


using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Hiperscan.Common.I18n;
using Hiperscan.Common.LogWriter;

namespace Hiperscan.Extensions.ApoIdentSoftwareUpgrade
{
    public partial class Upgrader
    {
        public Upgrader(Args args)
        {
            this.Options = args;
            this.Initialize();
        }

        private void Initialize()
        {
            if (String.IsNullOrEmpty(this.Options.LogFile))
                this.Options.LogFile.Value = Path.Combine(this.Options.WorkingDir, "upgrader-log.txt");

            string log_dir = Path.GetDirectoryName(this.Options.LogFile);
            if (Directory.Exists(log_dir) == false)
                Directory.CreateDirectory(log_dir);

            if (Directory.Exists(this.Options.WorkingDir) == false)
            {
                Directory.CreateDirectory(this.Options.WorkingDir);
                new DirectoryInfo(Path.GetDirectoryName(this.Options.WorkingDir)).Attributes = FileAttributes.Hidden;
            }

            if (this.Options.DownloadUpgrades == true)
                this.Options.LookForUpgrades.Value = true;

            if (this.Options.InstallUpgrades == true)
                this.Options.ShowAvailableUpgrades.Value = true;

            if (this.Options.DownloadUpgrades == false &&
                this.Options.InstallUpgrades == false &&
                this.Options.LookForUpgrades == false &&
                this.Options.ShowAvailableUpgrades == false)
                this.Options.LookForUpgrades.Value = true;

            Console.SetOut(new LogWriter(this.Options.LogFile, 1));

            this.VersionSearcher = new VersionSearcher(this.Options.LocaleType);
            this.LinkManager = new LinkManager(this.Options.LocaleType);

            Console.WriteLine("Initialize upgrader ...");
            Console.WriteLine("Version: {0}", this.Version);
            Console.WriteLine("Call: {0}", String.Join(" ", this.Options.AllArgs));
            Console.WriteLine("IsTestMode:              {0}", this.LinkManager.IsTestMode);
            Console.WriteLine("Working directory:       {0}", this.Options.WorkingDir.Value);
            Console.WriteLine("Log-File:                {0}", this.Options.LogFile.Value);
            Console.WriteLine("Download upgrades:       {0}", this.Options.DownloadUpgrades.Value);
            Console.WriteLine("Look for upgrades:       {0}", this.Options.LookForUpgrades.Value);
            Console.WriteLine("Show available upgrades: {0}", this.Options.ShowAvailableUpgrades.Value);
            Console.WriteLine("Install upgrades:        {0}", this.Options.InstallUpgrades.Value);
            Console.WriteLine("Locale type:             {0}", this.Options.LocaleType.Value);
            Console.WriteLine("Delay in days + offset:  {0}", this.Options.DelayInDays.Value);

            this.CheckData();
            this.SearchInstalledVersions();
        }

        private void SearchInstalledVersions()
        {
            Console.WriteLine("\n\nRead installed versions ...\n");
            Console.WriteLine("Quickstep-Version:        {0}", this.VersionSearcher.GetFullVersion(ProjectType.QuickStep));
            Console.WriteLine("IdentModule-Version:      {0}", this.VersionSearcher.GetFullVersion(ProjectType.IdentModule));
            Console.WriteLine("IdentModule-Locale:       {0}", this.VersionSearcher.GetModuleLocale(ProjectType.IdentModule));
            Console.WriteLine("QuantifierModule-Version: {0}", this.VersionSearcher.GetFullVersion(ProjectType.QuantifierModule));
            Console.WriteLine("QuantifierModule-Locale:  {0}", this.VersionSearcher.GetModuleLocale(ProjectType.QuantifierModule));
            Console.WriteLine();
            Console.WriteLine();
        }

        private void CheckData()
        {
            if (this.IsWindows == false)
                throw new Exception("Operating System is not supported");

            if (this.VersionSearcher.GetFullVersion(ProjectType.QuickStep) == VersionSearcher.NOT_AVAILABLE)
                throw new Exception("QuickStep seems to be not installed or version is older than 2.4.");
        }

        public void Start()
        {
            if (this.Options.ShowAvailableUpgrades)
            {
                Console.WriteLine("\nShow available ppgrades ...\n");
                this.ShowAvailableUpgrades();
                if (this.Options.InstallUpgrades == false)
                    return;
            }

            if (this.Options.InstallUpgrades)
            {
                Console.WriteLine("\nInstall upgrades ...\n");
                this.Install();
                return;
            }

            if (this.Options.LookForUpgrades)
            {
                Console.WriteLine("\nLook for upgrades ...\n");
                this.Lookup();

                if (this.Options.DownloadUpgrades == false)
                    return;
            }

            Console.WriteLine("Download upgrades ...");
            this.DownLoad();
        }

        private string Version
        {
            get
            {
                return Assembly.GetEntryAssembly().GetName().Version.ToString();
            }
        }

        private string GetFullDownloadDirectoryName(CatalogLocale.LocaleType locale)
        {
            return Path.Combine(this.Options.WorkingDir, locale.ToString());
        }

        private List<FileInfo> GetDownloadFiles(LookupUnit lookup_unit)
        {
            DirectoryInfo dir = new DirectoryInfo(this.GetFullDownloadDirectoryName(lookup_unit.ProjectLocale));
            if (dir.Exists == false)
                return new List<FileInfo>();

            List<FileInfo> files = new List<FileInfo>();
            foreach (FileInfo file in dir.GetFiles())
            {
                if (lookup_unit.FileRegex.Match(file.Name).Success == false)
                    continue;

                files.Add(file);
            }

            return files;
        }

        private bool IsWindows
        {
            get
            {
                return Environment.OSVersion.Platform == PlatformID.Win32NT;
            }
        }


        private Args Options { get; set; }
        private VersionSearcher VersionSearcher { get; set; }
        private LinkManager LinkManager { get; set; }

        private LookupUnit QuickStepLookupUnit { get; set; }
        private LookupUnit IdentModuleLookupUnit { get; set; }
        private LookupUnit QuantifierModuleLookopUnit { get; set; }
    }
}
