using SEI2.TestConsole.SEI2ReportProxy;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace SEI2.TestConsole.Bundles
{
    public class BundleExample
    {
        private BundleDataCreator dc = new BundleDataCreator();

        public static void Call(string args)
        {
            var split = args?.Split(' ');
            if (string.IsNullOrEmpty(args) || split?.Length != 2)
            {
                Console.WriteLine($"Wrong args: {args}.");
                return;
            }

            switch (split[1])
            {
                case "1":
                    new BundleExample().Example1();
                    break;
                case "2":
                    new BundleExample().Example2();
                    break;
                case "3":
                    new BundleExample().Example3();
                    break;
                case "4":
                    new BundleExample().Example4();
                    break;
                case "5":
                    new BundleExample().Example5();
                    break;
                case "6":
                    new BundleExample().Example6();
                    break;

                default:
                    Console.WriteLine($"Unknown example: {args}");
                    break;
            }
        }

        public void Example1()
        {
            LogExampleStart("No server side sorting");

            var entries = new List<SEI2DataContractBundleEntry>();
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 1));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 2));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 4));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 3));

            BundleSender.Process(entries);
        }

        public void Example2()
        {
            LogExampleStart("Server side sorting");

            var entries = new List<SEI2DataContractBundleEntry>();
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 4));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 0));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 1));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 2));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 4));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 5));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 2));

            BundleSender.Process(entries, true);
        }

        public void Example3()
        {
            LogExampleStart("Bundle error");

            var entries = new List<SEI2DataContractBundleEntry>();
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 1));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 2, "UserCreate")); // Illigal action (Cannot be used in Bundle).
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 3));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 4, "UnknownAction")); // Illigal action (Unknown).

            BundleSender.Process(entries);
        }

        public void Example4()
        {
            LogExampleStart("Entry error");

            List<SEI2DataContractBundleEntry> entries = new List<SEI2DataContractBundleEntry>();
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 1));
            entries.Add(this.CreateEntry(dc.ReportDataContractWithError(), 2));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 3));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 4));

            BundleSender.Process(entries);
        }

        public void Example5()
        {
            LogExampleStart("Cancel and Update entries");

            Console.WriteLine("Creating schemas");

            List<SEI2DataContractBundleEntry> entries = new List<SEI2DataContractBundleEntry>();
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 1));
            entries.Add(this.CreateEntry(dc.ReportDataContract(), 2));

            var response = BundleSender.Process(entries);
            if (response != null && response.success && response.entryResults?.Length == 2)
            {
                var schemaEntry1 = response.entryResults[0] as SEI2DataContractResponseBundleEntrySchemaReport;
                var schemaEntry2 = response.entryResults[1] as SEI2DataContractResponseBundleEntrySchemaReport;
                Console.WriteLine("Updating / Cancel existing schemas:");
                Console.WriteLine($"- Updating schema: {schemaEntry1.schemaGuid} ({schemaEntry1.schemaId}).");
                Console.WriteLine($"- Cancelling schema: {schemaEntry2.schemaGuid} ({schemaEntry2.schemaId}).");

                List<SEI2DataContractBundleEntry> cancelAndUpdateEntries = new List<SEI2DataContractBundleEntry>();
                cancelAndUpdateEntries.Add(this.CreateEntry(dc.UpdateDataContract(schemaEntry1.schemaGuid), 1));
                cancelAndUpdateEntries.Add(this.CreateEntry(dc.CancelDataContract(schemaEntry2.schemaGuid), 2, "SchemaCancel"));

                BundleSender.Process(cancelAndUpdateEntries);
            }
        }


        public void Example6()
        {
            LogExampleStart("Get user details");

            List<SEI2DataContractBundleEntry> entries = new List<SEI2DataContractBundleEntry>();
            entries.Add(this.CreateEntry(dc.UserGetContract(), 1, "PerformUserMgmt"));

            BundleSender.Process(entries);
        }


        private SEI2DataContractBundleEntry CreateEntry(string serializedDataContract, int importOrder, string action = "SchemaReport")
        {
            SEI2DataContractBundleEntry result = new SEI2DataContractBundleEntry()
            {
                action = action,
                importOrder = importOrder,
                dataContract = serializedDataContract,
                entryId = Guid.NewGuid().ToString()
            };

            return result;
        }

        private void LogExampleStart(string description, [CallerMemberName] string callerName = "")
        {
            Console.WriteLine("--------------------------");
            Console.WriteLine($"- {callerName}:");
            Console.WriteLine($"- - {description}.");
            Console.WriteLine("--------------------------");
            Console.WriteLine("");
        }

        
    }
}
