using Ion.Sdk.Idi;
using Ion.Tools.Models.XmlDataExport;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using Extensions = Ion.Tools.Models.XmlDataExport.Extensions;

namespace Ion.Sdk.DemoApp.Components
{
    public abstract class WorkspaceFileExporter : FileExporter<Idi.Workspace>
    {
        #region -=Exporter implementations=-

        public class Json : WorkspaceFileExporter
        {
            public override string CommandName { get; } = "Export to JSON => Tree structure";
            public override string SaveDialogFilter { get; } = "json|*.json";
            public override Task ExportWorkspace(Idi.Workspace workspace, string filenameWithPath)
                => Task.Run(() => System.IO.File.WriteAllText(filenameWithPath, workspace.ToJson()));
        }

        public class JsonFlat : WorkspaceFileExporter
        {
            public override string CommandName { get; } = "Export to JSON => Flat structure";
            public override string SaveDialogFilter { get; } = "json|*.json";
            public override Task ExportWorkspace(Idi.Workspace workspace, string filenameWithPath)
                => Task.Run(() => System.IO.File.WriteAllText(filenameWithPath, workspace.ToJson(flatStructure: true)));
        }

        public class Xml : WorkspaceFileExporter
        {
            public override string CommandName { get; } = "Export to XML => Tree structure";
            public override string SaveDialogFilter { get; } = "xml|*.xml";
            public override Task ExportWorkspace(Idi.Workspace workspace, string filenameWithPath)
                => Task.Run(() => System.IO.File.WriteAllText(filenameWithPath, workspace.ToXml()));
        }


        public class XmlFlat : WorkspaceFileExporter
        {
            public override string CommandName { get; } = "Export to XML => Flat structure";
            public override string SaveDialogFilter { get; } = "xml|*.xml";
            public override Task ExportWorkspace(Idi.Workspace workspace, string filenameWithPath)
                => Task.Run(() => System.IO.File.WriteAllText(filenameWithPath, workspace.ToXml(flatStructure: true)));
        }

        public class XmlSchemas : WorkspaceFileExporter
        {
            public override string CommandName { get; } = "Export XML schema(s) => Tree structure";
            public override string SaveDialogFilter { get; } = string.Empty; // = "xds|*.xsd";
            public override bool RequiresWorkspace => false;
            public override bool IsMultiFileExporter => true;

            public override Task ExportWorkspace(Idi.Workspace workspace, string filenameWithPath)
            {

                var schemaSet = Extensions.GetXmlSchemaSet();

                var path = Path.GetDirectoryName(filenameWithPath);

                foreach (XmlSchema schema in schemaSet.Schemas())
                {
                    var filename = Regex.Match(schema.TargetNamespace.TrimEnd('/'), "https?:\\//(.*)/?").Groups[1].Value.Replace("/", ".");
                    if (Path.GetExtension(filename).ToLower() != ".xsd")
                        filename = $"{filename}.xsd";

                    using (var file = new FileStream(Path.Combine(path, filename), FileMode.Create, FileAccess.ReadWrite))
                    {
                        var writer = new XmlTextWriter(file, new UTF8Encoding()) { Formatting = Formatting.Indented };
                        schema.Write(writer);
                    }
                }

                return Task.FromResult(true);
            }
        }

        public class XmlSchemasFlat : WorkspaceFileExporter
        {
            public override string CommandName { get; } = "Export XML schema(s) => Flat structure";
            public override string SaveDialogFilter { get; } = string.Empty; // = "xds|*.xsd";
            public override bool RequiresWorkspace => false;
            public override bool IsMultiFileExporter => true;

            public override Task ExportWorkspace(Idi.Workspace workspace, string filenameWithPath)
            {

                var schemaSet = Extensions.GetXmlSchemaSet(flatStructure: true);

                var path = Path.GetDirectoryName(filenameWithPath);

                foreach (XmlSchema schema in schemaSet.Schemas())
                {
                    var filename = Regex.Match(schema.TargetNamespace.TrimEnd('/'), "https?:\\//(.*)/?").Groups[1].Value.Replace("/", ".");
                    if (Path.GetExtension(filename).ToLower() != ".xsd")
                        filename = $"{filename}.xsd";

                    using (var file = new FileStream(Path.Combine(path, filename), FileMode.Create, FileAccess.ReadWrite))
                    {
                        var writer = new XmlTextWriter(file, new UTF8Encoding()) { Formatting = Formatting.Indented };
                        schema.Write(writer);
                    }
                }

                return Task.FromResult(true);
            }
        }

        #endregion

    }
}
