using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI;
using log4net;
using System;
using System.Diagnostics;
using RevitToIfcConverter.Core.Tools;
using Common;
using Autodesk.Revit.UI.Events;

namespace RevitToIfcConverter.Core
{
    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    [Journaling(JournalingMode.NoCommandData)]
    public class ExternalApplication : IExternalApplication
    {
        private static ILog _logger;
        private PipeServer _converterPipeServer;

        public Result OnStartup(UIControlledApplication application)
        {
            try
            {
                _logger = Logger.InitLog();
                _logger.Info($"{nameof(ExternalApplication)}: initializing");

                application.ControlledApplication.ApplicationInitialized += ApplicationInitialized;

                application.DialogBoxShowing += DialogBoxShowing;
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw;
            }

            return Result.Succeeded;
        }

        private void DialogBoxShowing(object sender, DialogBoxShowingEventArgs e)
        {
            if (e.DialogId == "Dialog_Revit_DocWarnDialog")
                e.OverrideResult(2); //WinForms.DialogResult.Cancel
        }

        private void ApplicationInitialized(object sender, ApplicationInitializedEventArgs e)
        {
            try
            {
                var pid = Process.GetCurrentProcess().Id;
                var pipeServerAddress = RevitIntegration.BuildConverterPipeAddress(revitProcessId: pid);

                var converterImplementation = new ConverterImplementation(_logger);
                var handler = new ConvertToIfcExternalEvent(converterImplementation);
                ExternalEvent exEvent = ExternalEvent.Create(handler);
                converterImplementation.SetExEvent(exEvent);

                _converterPipeServer = new PipeServer(strategy: converterImplementation, address: pipeServerAddress);
                PipeClient.SendRevitAppInitialized(pipeAddress: RevitIntegration.BuildInitializationPipeAddress(pid));
                _logger.Info($"{nameof(ExternalApplication)}: ready");
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw;
            }
        }

        public Result OnShutdown(UIControlledApplication application)
        {
            _converterPipeServer?.Dispose();
            return Result.Succeeded;
        }
    }
}
