// Created with MonoDevelop
//
//    Copyright (C) 2017 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.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;


namespace Hiperscan.Common.IO
{

    public static class FileIOHelper
    {
        private static Mutex file_char_mutex = new Mutex();
        private static List<char> file_chars = null;


        public static string MakeSubstanceClassToFileName(string name)
        {
            return FileIOHelper.ConvertToValidFilename(name);
        }

        public static string ConvertToValidFilename(string name)
        {
            name = FileIOHelper.RemoveUmlauts(name);
            string new_name = string.Empty;
            foreach (char c in name)
            {
                if (FileIOHelper.ValidFileChars.Contains(c) == true)
                    new_name += c.ToString();
                else
                    new_name += "_";
            }

            return new_name;
        }

        public static string ConvertToValidPathName(string name)
        {
            name = FileIOHelper.RemoveUmlauts(name);

            string new_name = string.Empty;
            foreach (char c in name)
            {
                if (FileIOHelper.ValidFileChars.Contains(c) == true ||
                    FileIOHelper.ValidDirectorySeparators.Contains(c))
                    new_name += c.ToString();
                else
                    new_name += "_";
            }

            return new_name;
        }

        public static string ConvertTextContentToUtf8(string file_name, Encoding source_encoding)
        {
            string utf8_content = string.Empty;

            using (StreamReader sr = new StreamReader(file_name, source_encoding))
            {
                string encoding_content = sr.ReadToEnd();
                byte[] encoding_bytes = source_encoding.GetBytes(encoding_content);

                Encoding utf8 = Encoding.UTF8;
                byte[] utf8_bytes = Encoding.Convert(source_encoding, utf8, encoding_bytes);
                char[] utf8_chars = new char[utf8.GetCharCount(utf8_bytes, 0, utf8_bytes.Length)];

                utf8.GetChars(utf8_bytes, 0, utf8_bytes.Length, utf8_chars, 0);
                utf8_content = new string(utf8_chars);
            }
            return utf8_content;
        }

        public static List<char> ValidFileChars
        {
            get
            {
                lock (FileIOHelper.file_char_mutex)
                {
                    if (FileIOHelper.file_chars == null)
                    {
                        FileIOHelper.file_chars = new List<char>();
                        for (int i = 45; i <= 46; i++)
                        {
                            FileIOHelper.file_chars.Add((char)i);
                        }

                        for (int i = 48; i < 58; i++)
                        {
                            FileIOHelper.file_chars.Add((char)i);
                        }

                        for (int i = 65; i <= 90; i++)
                        {
                            FileIOHelper.file_chars.Add((char)i);
                        }

                        for (int i = 97; i <= 122; i++)
                        {
                            FileIOHelper.file_chars.Add((char)i);
                        }
                    }
                }

                return FileIOHelper.file_chars;
            }
        }

        public static List<char> ValidDirectorySeparators
        {
            get
            {
                if (Environment.OSVersion.Platform == PlatformID.Unix)
                    return new List<char>(new char[] { '/' });

                return new List<char>(new char[] { '\\', '/' });
            }
        }

        public static string RemoveUmlauts(string text)
        {
            text = text ?? string.Empty;
            text = text.Replace("Ä", "Ae");
            text = text.Replace("Ö", "Oe");
            text = text.Replace("Ü", "Ue");
            text = text.Replace("ä", "ae");
            text = text.Replace("ö", "oe");
            text = text.Replace("ü", "ue");
            text = text.Replace("ß", "ss");

            return text;
        }

        public static bool FilesAreEqual(string fname1, string fname2)
        {
            return File.ReadAllBytes(fname1).SequenceEqual(File.ReadAllBytes(fname2));
        }

        public static Stream ToStream(this byte[] value)
        {
            return new MemoryStream(value);
        }

        public static void ToFile(this byte[] value, string file)
        {
            using (FileStream file_stream = File.Open(file, FileMode.OpenOrCreate))
            {
                file_stream.Write(value, 0, value.Length);
            }
        }

        public static bool IsText(string text)
        {
            Regex replace = new Regex(@"\s");
            Regex search = new Regex(@"\p{C}");
            text = replace.Replace(text ?? string.Empty, string.Empty);
            return search.Match(text).Success == false;
        }

        public static class QuickStepConfigPath
        {
            public const string DEFAULT_PROFILE_NAME = "evidencehere";
            public const string DEFAULT_CONFIG_FILE_NAME = "user.config";
            public const string CONVERSION_COOKIE = "ksdafjsfadkjk";

            public static string GetDirPath(string profile_name)
            {
                return Path.Combine(QuickStepConfigPath.ReadFirstPartOfConfigPath(true),
                                    QuickStepConfigPath.GetConfigDirExtension(profile_name, true));
            }

            public static string OldFolder(string profile_name)
            {
                return Path.Combine(QuickStepConfigPath.ReadFirstPartOfConfigPath(false),
                                    QuickStepConfigPath.GetConfigDirExtension(profile_name, false));
            }

            public static bool FolderChanged(string profile_name)
            {
                return QuickStepConfigPath.GetDirPath(profile_name) != QuickStepConfigPath.OldFolder(profile_name);
            }

            private static string ReadFirstPartOfConfigPath(bool new_config_file)
            {
                string path = Environment.GetEnvironmentVariable(Env.QuickStep.CONFIG_DIR, EnvironmentVariableTarget.Machine);

                if (string.IsNullOrEmpty(path) == true)
                {
                    if (new_config_file)
                        path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                    else
                        path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                }

                return path;
            }

            private static string GetConfigDirExtension(string profile_name, bool new_config_file)
            {
                string app_name = "quickstep";
                string version = new_config_file == true ? "2.0.0.0" : "1.0.0.0";
                return Path.Combine(string.Format("{0}_{1}", app_name, profile_name), version);
            }
        }
    }
}