using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using Microsoft.WindowsAPICodePack.Dialogs;
using System.Security.Cryptography;

namespace DatGenerator
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string sourceFolder = "";
        string destinationFolder = "";

        private void btnSourceFolder_Click(object sender, EventArgs e)
        {
            CommonOpenFileDialog dialog = new CommonOpenFileDialog();
            dialog.InitialDirectory = textSourceFolder.Text;

            // dialog.IsFolderPicker = true;

            if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
            {
                textSourceFolder.Text = dialog.FileName;
                sourceFolder = dialog.FileName;
            }
        }

        private void btnDestinationFolder_Click(object sender, EventArgs e)
        {
            CommonOpenFileDialog dialog = new CommonOpenFileDialog();
            dialog.InitialDirectory = textDestinationFolder.Text;

            // dialog.IsFolderPicker = true;

            if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
            {
                textDestinationFolder.Text = dialog.FileName;
                destinationFolder = dialog.FileName;
            }
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            if (!Directory.Exists(sourceFolder))
            {
                MessageBox.Show("Source folder does not exist!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else if (!Directory.Exists(destinationFolder))
            {
                MessageBox.Show("Destination folder does not exist!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                var files = Directory.EnumerateFiles(sourceFolder, "*.*", SearchOption.AllDirectories);

                string previousDir = "";
                string currentDir = "";
                string[] dirSplit;
                string currentFilename = "";
                // Last dir in current dir string
                string lastDir = "";

                DateTime dateTime = DateTime.UtcNow.Date;
                var date = dateTime.ToString("yyyy-MM-dd");
                string headerDescription = CreateTosecVersion(currentDir) + " (TOSEC-v" + date + ")";


                //int dirCount;
                //var newDat = true;

                try
                {
                    foreach (string file in files)
                    {
                        currentDir = Path.GetDirectoryName(file);
                        currentFilename = Path.GetFileName(file);

                        dirSplit = Path.GetDirectoryName(file).Split(Path.DirectorySeparatorChar);
                        lastDir = dirSplit[-1];

                        // create tosecfile class, move functions to there
                        var md5 = CreateMD5(file);
                        var sha1 = CreateSHA1(file);


                        // Create XML Header
                        XElement header =
                            new XElement("header",
                                new XElement("name", CreateTosecVersion(currentDir)),
                                new XElement("description", headerDescription),
                                new XElement("category", CreateCategory(currentDir)),
                                new XElement("version", date),
                                new XElement("author", ""),
                                new XElement("email", "contact@tosecdev.org"),
                                new XElement("homepage", "TOSEC"),
                                new XElement("url", "http://www.tosecdev.org")
                                );

                        if (currentDir == previousDir || String.IsNullOrEmpty(previousDir))
                        {
                            if (lastDir == Path.GetFileNameWithoutExtension(currentFilename) || dirSplit[-2] == "multipart")
                            {
                                // Multipart
                            }
                            else
                            {
                                // singlepart
                            }
                        }
                        else
                        {
                            // Save dat + generate new dat
                            // output count to debug window
                            // Save to TOSEC/PIX/ISO subdirs - category
                        }
                        previousDir = currentDir;
                    }
                }
                catch (Exception)
                {

                }
            }
        }

        // Parse source dir
        // Directory.EnumerateFiles

        // hash files md5/sha1/crc

        // compare vs previous dir - changes = new dat

        // todo - later - check vs TNC

        private string CreateTosecVersion(string path)
        {
            var rootDir = path.Replace(sourceFolder, "").Split(Path.DirectorySeparatorChar);
            string tosecString = "";
            int count = rootDir.Count();

            // right now we Assume - TODO validate against system xml
            if (rootDir[0].Contains("tosec") || rootDir[0].Contains("pix") || rootDir[0].Contains("iso"))
            {
                // make sure category isn't added as well
                count--;
            }

            for (int i = 1; i <= count; i++)
            {
                tosecString += rootDir[i];
                if (i <= count)
                {
                    tosecString += " - ";
                }
            }
            return tosecString;
        }

        private string CreateCategory(string path)
        {
            var rootDir = path.Replace(sourceFolder, "").Split(Path.DirectorySeparatorChar);
            string tosecString = "";

            // right now we Assume - TODO validate against system xml
            if (rootDir[0].Contains("tosec") || rootDir[0].Contains("pix") || rootDir[0].Contains("iso"))
            {
                return tosecString.ToUpper();
            }
            else
            {
                // Assume default category if all else fails
                return "TOSEC";
            }
        }

        private string CreateMD5(string file)
        {
            var md5 = MD5.Create();
            var stream = File.OpenRead(file);
            return Encoding.Default.GetString(md5.ComputeHash(stream));
        }

        private string CreateSHA1(string file)
        {
            var sha1 = SHA1.Create();
            var stream = File.OpenRead(file);
            return Encoding.Default.GetString(sha1.ComputeHash(stream));
        }

        //private string CreateCRC32(string file)
        //{
        //    var crc = "";
        //}
    }
}
