using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Appium;

namespace Tests.E2ETests {
    public class AppSession : IDisposable {

        private const int WaitForAppLaunch = 3;
        private readonly string WinAppDriverUrl;
        public readonly WindowsDriver<WindowsElement> App;
        public readonly WindowsDriver<WindowsElement> Desktop;

        public AppSession(string appPath, string? appArgs, string winAppDriverUrl) {
            WinAppDriverUrl = winAppDriverUrl;
            var appiumOptions = new AppiumOptions();
            appiumOptions.AddAdditionalCapability("app", appPath);
            if (appArgs != null)
                appiumOptions.AddAdditionalCapability("appArguments", appArgs);
            appiumOptions.AddAdditionalCapability("deviceName", "WindowsPC");
            appiumOptions.AddAdditionalCapability("ms:waitForAppLaunch", WaitForAppLaunch);
            App = new WindowsDriver<WindowsElement>(new Uri(WinAppDriverUrl), appiumOptions);
            Assert.That(App, Is.Not.Null);
            Assert.That(App.SessionId, Is.Not.Null);
            App.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1.5);
            var desktopOptions = new AppiumOptions();
            desktopOptions.AddAdditionalCapability("app", "Root");
            desktopOptions.AddAdditionalCapability("deviceName", "WindowsPC");
            Desktop = new WindowsDriver<WindowsElement>(new Uri(WinAppDriverUrl), desktopOptions);
        }

        public WindowsDriver<WindowsElement> CreateWindowDriver(string windowName) {
            var window = Desktop.FindElementByAccessibilityId(windowName);
            var windowHandle = int.Parse(window.GetAttribute("NativeWindowHandle")).ToString("x"); // Convert to Hex
            var appiumOptions = new AppiumOptions();
            appiumOptions.AddAdditionalCapability("appTopLevelWindow", windowHandle);
            return new WindowsDriver<WindowsElement>(new Uri(WinAppDriverUrl), appiumOptions);
        }

        public void Dispose() {
            GC.SuppressFinalize(this);
            App.Close();
            try {
                Desktop.FindElement(By.Name("Ja")).Click();
            } catch { }
            App.Dispose();
            Desktop.Close();
            Desktop.Dispose();
        }
    }
}