// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2024, 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.IO;

using Hiperscan.AnalysisModule;
using Hiperscan.AnalysisModule.Identification;
using Hiperscan.Common;
using Hiperscan.ApoIdentCommon.ApoConfig;
using Hiperscan.Unix;

namespace Hiperscan.ApoIdentCore.SectionManager.Substance
{

#pragma warning disable RECS0022 // catch-Klausel, die System.Exception abfängt und keinen Text aufweist

    public partial class SubstancePdfs
    {
        public void ShowAdditionalTestPdf(AnalysisType analysis_type, string model_class_name = null)
        {
            RemoteSettings settings = this.SubstanceManager.GetRemoteSettings(analysis_type);

            if (settings.UpdateAdditionalTestsPdfs)
            {
                string message = String.Format(Catalog.GetString("An error occurred while getting the document from the {0}."),
                                               analysis_type.GetProductName());

                throw new Exception(message);
            }

            string file = this.FileSystem.GetAdditionalTestFile(analysis_type, model_class_name);
            if (false == FileIO.ExistsFile(file))
                throw new Exception(Catalog.GetString("Cannot find the file."));

            Process.OpenUri("file://" + file.Replace("\\", "/"));
        }

        public void UpdateAdditionalTestsPdfs(AnalysisType analysis_type)
        {
            try
            {
                Console.WriteLine("UpdateAdditionalTestsPdfs() for {0} ...", analysis_type.GetProductName());

                string dir = this.FileSystem.GetAdditionalDocuDir(analysis_type);
                FileIO.RecreateDirectory(dir, this.NeedUpdateAdditionalDocuments(analysis_type));

                this.UpdateAllAdditionalTestDocuments(analysis_type);
                this.SubstanceManager.GetRemoteSettings(analysis_type).UpdateAdditionalTestsPdfs = false;
            }
            catch (Exception ex)
            {
                Console.WriteLine("UpdateAdditionalTestsPdfs() failed: {0}", ex);
            }
        }

        private void UpdateAllAdditionalTestDocuments(AnalysisType analysis_type)
        {
            if (analysis_type == AnalysisType.Identification)
            {
                this.UpdateIdentModuleAdditionalTestDocu();
                return;
            }

            foreach (IdentModelClass model_class in this.SubstancesCatalog.AdditionalTestModelClasses)
            {
                if (model_class.DatabaseInfo.AnyalysisType == AnalysisType.Quantification)
                {
                    if (model_class.DatabaseInfo.AnyalysisType != analysis_type)
                        continue;
                    try
                    {
                        string file = this.FileSystem.GetAdditionalTestFile(analysis_type, model_class.Name);
                        if (this.NeedUpdateAdditionalDocuments(analysis_type, file) == false)
                            continue;

                        FileIO.DeleteFile(file, true);

                        byte[] stream = this.SubstanceManager.GetAdditionalTestDocument(model_class);
                        using (FileStream fs = new FileStream(file, FileMode.CreateNew))
                        {
                            fs.Write(stream, 0, stream.Length);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Cannot read additional test document {0}: {1}",
                                      model_class.Name,
                                      ex.Message);
                    }
                }
            }
        }

        private void UpdateIdentModuleAdditionalTestDocu()
        {
            try
            {
                string file = this.FileSystem.GetAdditionalTestFile(AnalysisType.Identification);
                if (this.NeedUpdateAdditionalDocuments(AnalysisType.Identification, file) == false)
                    return;

                FileIO.DeleteFile(file, true);

                byte[] stream = this.SubstanceManager.GetAdditionalTestDocument();
                using (FileStream fs = new FileStream(file, FileMode.CreateNew))
                {
                    fs.Write(stream, 0, stream.Length);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Cannot read additional test document {0}: {1}",
                                  DefaultNames.IdentServer.ADDITIONAL_TESTS_FILE,
                              ex.Message);
            }
        }


        private bool NeedUpdateAdditionalDocuments(AnalysisType analysis_type, string file = null)
        {
            if (String.IsNullOrEmpty(file) == false)
            {
                if (false == FileIO.ExistsFile(file))
                    return true;
            }

            return this.SubstanceManager.GetRemoteSettings(analysis_type).UpdateAdditionalTestsPdfs;
        }
    }

#pragma warning restore RECS0022 // catch-Klausel, die System.Exception abfängt und keinen Text aufweist
}
