use alien_core::*;
use clap::Parser;
use std::{fs::File, io::Write as _};
use utoipa::OpenApi;

#[derive(OpenApi)]
#[openapi(components(schemas(
    Worker,
    WorkerCode,
    WorkerOutputs,
    ComputeCluster,
    CapacityGroup,
    MachineProfile,
    Daemon,
    DaemonCode,
    DaemonOutputs,
    Container,
    ContainerOutputs,
    ContainerCode,
    ContainerGpuSpec,
    ContainerAutoscaling,
    ContainerPort,
    ExposeProtocol,
    PublicEndpoint,
    WorkerPublicEndpoint,
    PublicEndpointOutput,
    PersistentStorage,
    HealthCheck,
    ResourceSpec,
    ReplicaStatus,
    ContainerStatus,
    LoadBalancerEndpoint,
    Resource,
    ResourceLifecycle,
    ResourceOutputs,
    ResourceRef,
    ResourceStatus,
    ResourceType,
    Stack,
    StackInputDefaultValue,
    StackInputDefinition,
    StackInputEnvironmentMapping,
    StackInputEnvironmentVariableType,
    StackInputKind,
    StackInputProvider,
    StackInputValidation,
    StackRef,
    StackState,
    StackStatus,
    StackResourceState,
    StackSettings,
    NetworkSettings,
    DomainSettings,
    CustomDomainConfig,
    CustomCertificateConfig,
    AwsCustomCertificateConfig,
    GcpCustomCertificateConfig,
    AzureCustomCertificateConfig,
    KubernetesCustomCertificateConfig,
    KubernetesSettings,
    KubernetesClusterSettings,
    KubernetesExposureSettings,
    KubernetesRouteProfile,
    KubernetesIngressRouteProfile,
    KubernetesGatewayRouteProfile,
    KubernetesRouteProviderOptions,
    KubernetesCertificateMode,
    KubernetesTlsSecretRef,
    ManagementConfig,
    AwsManagementConfig,
    GcpManagementConfig,
    AzureManagementConfig,
    Storage,
    StorageOutputs,
    Build,
    BuildOutputs,
    BuildStatus,
    BuildConfig,
    ArtifactRegistry,
    ArtifactRegistryOutputs,
    ServiceAccount,
    ServiceAccountOutputs,
    RemoteStackManagement,
    RemoteStackManagementOutputs,
    Vault,
    VaultOutputs,
    Kv,
    KvOutputs,
    Queue,
    QueueOutputs,
    PlatformPermissions,
    PermissionSet,
    PermissionSetReference,
    PermissionProfile,
    ManagementPermissions,
    AlienEvent,
    EventChange,
    DeploymentModel,
    UpdatesMode,
    TelemetryMode,
    HeartbeatsMode,
    ResourceHeartbeat,
    // App events (for function triggers)
    StorageEvent,
    StorageEventType,
    StorageEvents,
    QueueMessage,
    MessagePayload,
    ScheduledEvent,
    // Dev status types (for alien dev --status-file output)
    DevStatus,
    DevStatusState,
    AgentStatus,
    DevResourceInfo,
    // Commands protocol types
    CommandState,
    BodySpec,
    CommandResponse,
    ResponseHandling,
    Envelope,
    CreateCommandRequest,
    StorageUpload,
    CreateCommandResponse,
    UploadCompleteRequest,
    UploadCompleteResponse,
    CommandStatusResponse,
    SubmitResponseRequest,
    LeaseRequest,
    LeaseInfo,
    LeaseResponse,
    ReleaseRequest,
    ImportSourceKind,
    StackImportRequest,
    ImportedResource,
    StackImportResponse,
    AwsStorageImportData,
    AwsWorkerImportData,
    AwsQueueImportData,
    AwsKvImportData,
    AwsVaultImportData,
    AwsNetworkImportData,
    AwsServiceAccountImportData,
    AwsRemoteStackManagementImportData,
    AwsBuildImportData,
    AwsArtifactRegistryImportData,
    AwsComputeClusterImportData,
    GcpStorageImportData,
    GcpWorkerImportData,
    GcpQueueImportData,
    GcpKvImportData,
    GcpVaultImportData,
    GcpNetworkImportData,
    GcpServiceAccountImportData,
    GcpServiceActivationImportData,
    GcpRemoteStackManagementImportData,
    GcpBuildImportData,
    GcpArtifactRegistryImportData,
    GcpComputeClusterImportData,
    AzureStorageImportData,
    AzureWorkerImportData,
    AzureQueueImportData,
    AzureKvImportData,
    AzureVaultImportData,
    AzureNetworkImportData,
    AzureServiceAccountImportData,
    AzureServiceActivationImportData,
    AzureRemoteStackManagementImportData,
    AzureBuildImportData,
    AzureArtifactRegistryImportData,
    AzureComputeClusterImportData,
    AzureResourceGroupImportData,
    AzureContainerAppsEnvironmentImportData,
    AzureServiceBusNamespaceImportData,
    AzureStorageAccountImportData,
)))]
struct ApiDoc;

/// A simple program to export OpenAPI spec
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    /// Output path for the OpenAPI JSON file
    #[arg(short, long, default_value = "openapi.json")]
    output: String,
}

fn main() {
    let args = Args::parse();

    let mut file = File::create(&args.output).unwrap();
    file.write_all(ApiDoc::openapi().to_pretty_json().unwrap().as_bytes())
        .unwrap();
    println!("OpenAPI spec exported to {}", args.output);
}
