// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2018 Thomas Klose & Torsten Schache, 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.Text;

using Hiperscan.Common.IO;
using Hiperscan.Spectroscopy.IdentModule;
using Hiperscan.Spectroscopy.IdentServer;
using Hiperscan.Unix;


namespace Hiperscan.Extensions.ApoIdent
{
    public partial class IdentServerClient
    {
        private List<string> GetModelClassNames(AccessDatabaseInfo info)
        {
            this.Authentification.AccessDatabase = info;
            return this.Client.GetModelClassNames(this.Authentification);
        }

        public ApoIdentApplicationState LoadData(SubstanceManagement substance_db)
        {
            try
            {
                int max = 0;

                substance_db.StartLoading();

                Dictionary<AccessDatabaseInfo, List<string>> all_substance_classes = new Dictionary<AccessDatabaseInfo, List<string>>();

                foreach (AccessDatabaseInfo db_info in this.Databases)
                {
                    this.Authentification.AccessDatabase = db_info;
                    List<string> model_class_names = this.Client.GetModelClassNames(this.Authentification);
                    if (model_class_names.Count == 0)
                    {
                        Console.WriteLine("Database {0} does not have permissible classifiers.",
                                          Path.GetFileNameWithoutExtension(db_info.Name));
                        continue;
                    }
                    all_substance_classes.Add(db_info, model_class_names);
                    max += model_class_names.Count;
                }

                if (max == 0)
                    throw new Exception(Catalog.GetString("No permissible classifiers found."));

                int count = 0;
                max += 1;

                foreach (AccessDatabaseInfo db_info in all_substance_classes.Keys)
                {
                    this.Authentification.AccessDatabase = db_info;
                    foreach (string model_class_name in all_substance_classes[db_info])
                    {
                        this.Authentification.ModelClassName = model_class_name;
                        ModelClassInfo class_info = this.Client.GetModelClassInfo(this.Authentification);
                        class_info.InitResolver();
                        class_info.DatabaseInfo = db_info;
                        substance_db.AddModelClassToResolver(class_info);
                        substance_db.LoadingProgress(++count / (double)max);
                    }
                }

                substance_db.InitModelExtension();
                substance_db.Pdfs.CheckForPdfUpdates();
                substance_db.Pdfs.UpdateSubstancePdfs();
                substance_db.Pdfs.UpdateValidationDocument();
                substance_db.Pdfs.UpdateAdditionalTestsPdfs();
                substance_db.Pdfs.UpdateCertificate();
                substance_db.Pdfs.UpdateIMLicenseText();

                substance_db.LoadingProgress(1);
                substance_db.LoadingFinished();

                return ApoIdentApplicationState.None;
            }
            catch(Exception ex)
            {
                this.Exception = ex;
                this.ErrorMessage = ex.Message;
                return ApoIdentApplicationState.ConnectionLoadDataFailed;
            }    
        }

        public ModelClassExtensionInfo GetModelClassExtensionInfo()
        {
            return this.Client.GetModelClassExtensionInfo(this.Authentification);
        }

        public void UpdateAuthentificationSet(SubstanceManagement substance_db)
        {
            this.Authentification.AccessDatabase = substance_db.CurrentModelClass.DatabaseInfo;
            this.Authentification.SubstanceId    = substance_db.CurrentSubstance.Id;
            this.Authentification.ModelClassName = substance_db.CurrentModelClass.ModelClassName;
        }

        public byte[] GetValidationDocument(ModelClassInfo classifier)
        {
            return this.Client.GetValidationDocument(classifier.ModelClassName);
        }

        public byte[] GetAddtionalTestsPdf()
        {
            return this.Client.GetAdditionalTestPdf();
        }

        public byte[] GetPpnList()
        {
            try
            {
                return this.Client.GetPznList();
            }
            catch
            {
                return null;
            }
        }

        public byte[] GetSubstanceChangeLog()
        {
            return this.Client.GetUpdateChangesFile();
        }

        public string GetLicense()
        {
            using (Stream s = this.Client.GetLicense().ToStream())
            {
                using (StreamReader sr = new StreamReader(s, Encoding.UTF8))
                {
                    return sr.ReadToEnd();
                }
            }
        }

        public UpdateCertificateInfo GetUpdateCertificateData()
        {
            return this.Client.GetUpdateCertificateData();
        }
    }
}
