// 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.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using Hiperscan.Common.I18n;

namespace Hiperscan.Extensions.ApoIdentSoftwareUpgrade
{
    public class LookupUnit
    {

        public LookupUnit(ProjectType name, Locale.LocaleType locale, VersionLauncher launcher)
        {
            this.ProjectName = name;
            this.ProjectLocale = locale;
            this.VersionResult = new VersionComparerer.Result();

            if (this.ProjectName == ProjectType.QuickStep)
            {
                this.FileRegex = new Regex(@"QuickStep_\d+\.\d+\.\d+.+\.exe");
                this.RegistryValue = launcher.GetFullQuickStepVersion();
            }
            else
            {
                this.FileRegex = new Regex(@"IdentModul_\d+\.\d+\.\d+.+\.exe");
                this.RegistryValue = launcher.GetFullIdentModuleVersion();
            }

            this.FileName = String.Empty;
        }

        public void SetFromLookup(string text)
        {
            this.filename = String.Empty;

            string value = this.LastModifiedRegex.Match(text).Value;
            if (String.IsNullOrEmpty(value))
                throw new Exception("Lookup - cannot find creation date.");

            value = value.Replace("Last-Modified: ", String.Empty);
            this.PublisherDate = DateTime.Parse(value, CultureInfo.InvariantCulture);


            value = this.ContentLengthRegex.Match(text).Value;
            if (String.IsNullOrEmpty(value))
                throw new Exception("Lookup - cannot find file content length.");

            value = value.Replace("Content-Length:", String.Empty);
            this.FileLength = Int32.Parse(value);


            value = this.FileRegex.Match(text).Value;
            if (String.IsNullOrEmpty(value))
                throw new Exception("Lookup - cannot find file name.");

            this.FileName = value;
        }

        public void SetFromDownloads(FileInfo file)
        {
            try
            {
                this.PublisherDate = file.CreationTime;
                this.FileLength = (int) file.Length;
                this.FileName = file.Name;

            }
            catch(Exception)
            {
                this.FileName = String.Empty;
            }
        }

        public void Write()
        {
            if (this.ProjectName == ProjectType.QuickStep)
                Console.WriteLine("Compare QuickStep versions:");
            else
                Console.WriteLine("Compare IdentModule versions:");


            if (this.IsValid == false)
            {
                Console.WriteLine("NO VALID DATA");
            }
            else
            {
                Console.WriteLine("Project:       {0}", this.ProjectName);
                Console.WriteLine("Locale:        {0}", this.ProjectLocale);
                Console.WriteLine("FileName:      {0}", this.FileName);
                Console.WriteLine("FileLength:    {0}", this.FileLength);
                Console.WriteLine("PublisherDate: {0}", this.PublisherDate);
                Console.WriteLine("RegistryValue: {0}", this.RegistryValue);
                Console.WriteLine("CanDownload:   {0}", this.CanDownload);
                Console.WriteLine("CanInstall:    {0}", this.CanInstall);
                Console.Write(this.VersionResult);
            }

            Console.WriteLine();
        }

        public bool IsDownloadFile(FileInfo other_file)
        {
            if (other_file.Exists == false)
                return false;

            if (this.FileName != other_file.Name)
                return false;

            return this.FileLength == other_file.Length;
        }


        public bool IsValid
        {
            get
            {
                return String.IsNullOrEmpty(this.FileName) == false;
            }
        }

        public bool CanDownload
        {
            get
            {
                if (this.IsValid == false)
                    return false;

                if (this.VersionResult == null)
                    return false;

                return this.VersionResult.UpgradeType != VersionComparerer.UpgradeType.None;
            }
        }

        public string TmpFileName
        {
            get
            {
                return this.ProjectName.ToString() + ".tmp";
            }
        }

        private string filename = String.Empty;
        public string FileName
        {
            get
            {
                return this.filename;
            }

            private set
            {
                this.filename = value;
                if (this.ProjectName == ProjectType.QuickStep)
                    this.VersionResult = VersionComparerer.CompareQSFileAndRegistry(this.filename, this.RegistryValue);
                else
                    this.VersionResult = VersionComparerer.CompareIMFileAndRegistry(this.filename, this.RegistryValue);
            }
        }

        public bool CanInstall { get; set; } = false;


        public DateTime PublisherDate { get; private set; } = DateTime.MaxValue;
        public int FileLength { get; private set; } = 0;

        public Locale.LocaleType ProjectLocale { get; private set; } = Locale.LocaleType.Unknown;
        public ProjectType ProjectName { get; private set; }

        private string RegistryValue { get; set; }
        public VersionComparerer.Result VersionResult { get; private set; }
        public string Url { get; set; } = string.Empty;

        public Regex FileRegex { get; set; } = null;
        private Regex LastModifiedRegex { get; set; } = new Regex(@"Last-Modified:.+GMT");
        private Regex ContentLengthRegex { get; set; } = new Regex(@"Content-Length: \d+");
    }
}
