/* Copyright Airship and Contributors */

#if canImport(AirshipKit)
import AirshipKit
#elseif canImport(AirshipCore)
import AirshipCore
#endif

import AirshipFrameworkProxy
import Capacitor

@MainActor
public final class AirshipCapacitorAutopilot: NSObject {

    public static let shared: AirshipCapacitorAutopilot = AirshipCapacitorAutopilot()

    private var pluginInitialized: Bool = false
    private var applicationDidFinishLaunching: Bool = false

    fileprivate var pluginConfig: PluginConfig?

    /*
     * In Capacitor 5, the order of initialization is:
     * - AppDelegate#applicationDidFinishLaunching
     * - onPluginInitialized
     * - onApplicationDidFinishLaunching
     *
     * We are going to be resilient to that order changing by tracking each state
     * any only attempting takeOff automatically after both onPluginInitialized
     * and onApplicationDidFinishLaunching are called on Autopilot.
     */

    @MainActor
    func onApplicationDidFinishLaunching() {
        AirshipProxy.shared.delegate = self 
        self.applicationDidFinishLaunching = true
        if self.pluginInitialized, self.applicationDidFinishLaunching {
            try? AirshipProxy.shared.attemptTakeOff()
        }
    }

    @MainActor
    public func onPluginInitialized(pluginConfig: PluginConfig?) {
        self.pluginInitialized = true
        self.pluginConfig = pluginConfig
        if self.pluginInitialized, self.applicationDidFinishLaunching {
            try? AirshipProxy.shared.attemptTakeOff()
        }
    }

    @MainActor
    func attemptTakeOff(json: Any) throws -> Bool {
        return try AirshipProxy.shared.takeOff(
            json: json,
        )
    }
}

extension AirshipCapacitorAutopilot: AirshipProxyDelegate {
    public func migrateData(store: AirshipFrameworkProxy.ProxyStore) {}
    
    public func loadDefaultConfig() -> AirshipConfig {
        var airshipConfig = (try? AirshipConfig.default()) ?? AirshipConfig()
        if let config = self.pluginConfig?.getObject("config") {
            do {
                let proxyConfig: ProxyConfig = try AirshipJSON.wrap(config).decode()
                airshipConfig.applyProxyConfig(proxyConfig: proxyConfig)
            } catch {
                AirshipLogger.error("Failed to parse config: \(error)")
            }
        }
        return airshipConfig
    }
    
    @MainActor
    public func onAirshipReady() {
        Airship.analytics.registerSDKExtension(
            AirshipSDKExtension.capacitor,
            version: AirshipCapacitorVersion.version
        )
    }
}


