using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using System.Management;
using Newtonsoft.Json;
using System.IO;
using System.Windows;
using System.Windows.Threading;
using Microsoft.WindowsAPICodePack.Dialogs;

namespace barry
{
    public class Methods
    {

        public string data_file_path = @".\barry.dat";


        public void read_config()
        {

        }

        /// <summary>
        /// returns the current drive letter
        /// </summary>
        /// <returns></returns>
        public string current_drive_letter()
        {
            return System.IO.Path.GetPathRoot(Environment.CurrentDirectory);
        }

        /// <summary>
        /// returns the current drive letter
        /// </summary>
        /// <returns></returns>
        public string computer_name()
        {
            return System.Environment.MachineName;
        }


        /// <summary>
        /// returns the current drive label
        /// </summary>
        /// <returns></returns>
        public string current_drive_label()
        {
            // current drive letter
            string driveLetter = current_drive_letter();

            System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();
            for (int i = 0; i < drives.Count(); i++)
            {
                if (drives[i].Name == driveLetter)
                {
                    if (drives[i].IsReady)
                    {
                        return drives[i].VolumeLabel;
                    }
                }

            }
            return "<unknwown>";
        }

        /// <summary>
        /// control that the program is launched from the source
        /// </summary>
        /// <returns></returns>
        public bool am_i_the_good_source()
        {
            // current drive letter
            string driveLetter = current_drive_letter();

            System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();
            //Console.WriteLine("Detected Drives: ");
            for (int i = 0; i < drives.Count(); i++)
            {
                if (drives[i].Name == driveLetter)
                {
                    if (drives[i].IsReady)
                    {
                        if (drives[i].VolumeLabel == "_OMASSOT")
                        {
                            return true;
                        }
                    }
                }

            }
            return false;
        }


        /// <summary>
        /// Finds the MAC address of the first operation NIC found.
        /// </summary>
        /// <returns>The MAC address.</returns>
        public string get_mac_adress()
        {
            string macAddresses = string.Empty;

            foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (nic.OperationalStatus == OperationalStatus.Up)
                {
                    macAddresses += nic.GetPhysicalAddress().ToString();
                    break;
                }
            }

            return macAddresses;
        }

        /// <summary>
        /// Get the unique identifier of the current computer (more reliable than mac adress)
        /// </summary>
        /// <returns>UUID (32 cars)</returns>
        public string get_cpu_uuid()
        {
            var procStartInfo = new ProcessStartInfo("cmd", "/c " + "wmic csproduct get UUID")
            {
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true
            };

            var proc = new Process() { StartInfo = procStartInfo };
            proc.Start();

            return proc.StandardOutput.ReadToEnd().Replace("UUID", string.Empty).Trim().ToUpper();
        }

        /// <summary>
        /// Get the unique identifier of the windows installation (more reliable than UUID)
        /// </summary>
        /// <returns>UUID (32 cars)</returns>
        public string get_machine_guid()
        {
            ManagementObject os = new ManagementObject("Win32_OperatingSystem=@");
            return (string)os["SerialNumber"];
        }


        // access to data file

        public Dictionary<string, BackupConfig> load_config_from_file()
        {
            string json;
            try
            {
                json = File.ReadAllText(data_file_path);
            }
            catch(FileNotFoundException)
            {
                json = "{}";
            }
            return JsonConvert.DeserializeObject<Dictionary<string, BackupConfig> >(json);
            // catch: JsonReaderException
        }

        public void save_config_to_file(Dictionary<string, BackupConfig> barry_config)
        {
            string json = JsonConvert.SerializeObject(barry_config, Formatting.Indented);
            File.WriteAllText(data_file_path, json);
        }
        
        public void register_this_cpu()
        {

            string machine_guid = get_machine_guid();

            Dictionary<string, BackupConfig> barry_config = load_config_from_file();

            if (barry_config.ContainsKey(machine_guid))
            {
                Console.WriteLine(">> this computer is already registered");
                return;
            }

            BackupConfig new_bkp = new BackupConfig();
            new_bkp.machine_guid = machine_guid;

            // add a select dir dialog box

            new_bkp.dir_path = @"";

            barry_config.Add(machine_guid, new_bkp);

            save_config_to_file(barry_config);

        }

        public BackupConfig load_this_cpu()
        {
            Dictionary<string, BackupConfig> barry_config = load_config_from_file();
            try
            {
                return barry_config[get_machine_guid()];
            }
            catch(KeyNotFoundException)
            {
                return null;
            }
        }

        public void save_this_cpu(BackupConfig bkp)
        {
            Dictionary<string, BackupConfig> barry_config = load_config_from_file();
            barry_config[get_machine_guid()] = bkp;
            save_config_to_file(barry_config);
        }

        /// <summary>
        /// returns true if dir1 is a subdir of dir2
        /// </summary>
        /// <param name="dir1"></param>
        /// <param name="dir2"></param>
        public bool is_subdir(string dir1, string dir2)
        {
            DirectoryInfo di1 = new DirectoryInfo(dir1);
            DirectoryInfo di2 = new DirectoryInfo(dir2);
            while (di1.Parent != null)
            {
                if (di1.Parent.FullName == di2.FullName)
                {
                    return true;
                }
                else di1 = di1.Parent;
            }
            return false;
        }

        public string select_directory_dialog(string title = "Select a directory", string initial_dir = "")
        {
            var dlg = new CommonOpenFileDialog();
            dlg.Title = title;
            dlg.IsFolderPicker = true;
            dlg.InitialDirectory = initial_dir;
            dlg.EnsurePathExists = true;
            dlg.ShowPlacesList = true;

            if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
            {
                var folder = dlg.FileName;
                return (string)folder;
            }
            return "";
        }





    }


}