#pragma once

#include "lite_backend_artifact_resolver.h"

#include <cstddef>
#include <string>
#include <vector>

namespace dragonx::wallet {

enum class LiteBackendArtifactContractLinkMode {
    ImportedLibrary,
    RuntimeDynamicLibrary,
    ExternalExecutable,
};

enum class LiteBackendArtifactContractStatus {
    ReadyForResolver,
    WaitingForContractOwner,
    WaitingForReadOnlyGate,
    WaitingForLinkMode,
    WaitingForArtifactPath,
    WaitingForArtifactKind,
    WaitingForAbiVersion,
    WaitingForSymbolInventory,
    WaitingForRequiredSymbols,
    WaitingForSignatureMetadata,
    RuntimeActionDisabled,
};

enum class LiteBackendArtifactContractIssue {
    ContractOwnerMissing,
    ReadOnlyGateMissing,
    RuntimeDynamicLinkDeferred,
    ExternalExecutableDeferred,
    ArtifactPathMissing,
    ArtifactKindNotLinkable,
    AbiVersionMissing,
    AbiVersionUnsupported,
    SymbolInventoryOwnerMissing,
    SymbolInventoryMissing,
    RequiredSymbolMissing,
    SignaturePolicyMissing,
    SignatureMetadataMissing,
    SignatureMetadataIncomplete,
    SignatureVerificationMissing,
    SignatureVerificationFailed,
    SignatureVerifiedArtifactShaMismatch,
    SignatureTrustMetadataMissing,
    ArtifactMutationRequested,
    DynamicLibraryLoadRequested,
    DynamicLibraryUnloadRequested,
    SymbolResolutionRequested,
    SdxlApiRequested,
    BridgeCallRequested,
    ServerConnectivityCheckRequested,
    WalletLifecycleRequested,
    SyncRequested,
    SyncStatusPollingRequested,
    WorkerQueueRequested,
    WalletStateMutationRequested,
    WalletPersistenceRequested,
    UploadRequested,
    SigningRequested,
    PublicationRequested,
};

struct LiteBackendArtifactContractSymbol {
    std::string logicalName;
    std::string abiName;
    bool returnsOwnedString = false;
    bool cleanupFunction = false;
    bool requiredForLifecycle = false;
    bool requiredForSync = false;
    bool requiredForServerCheck = false;
    bool requiredForShutdown = false;
};

struct LiteBackendArtifactContractInput {
    bool contractOwnerReady = false;
    bool readOnlyGateReady = false;
    std::string projectRoot;
    std::string artifactPath;
    LiteBackendArtifactPlatform platform = LiteBackendArtifactPlatform::Current;
    LiteBackendArtifactKind artifactKind = LiteBackendArtifactKind::Unknown;
    LiteBackendArtifactContractLinkMode linkMode = LiteBackendArtifactContractLinkMode::ImportedLibrary;
    std::string abiVersion;
    std::string artifactSha256;
    LiteBackendArtifactProvenanceMetadata provenance;
    LiteBackendArtifactSignatureVerificationMetadata signatureVerification;
    bool sdxlCompatible = false;
    bool symbolInventoryOwnerReady = false;
    std::vector<std::string> exportedSymbols;

    bool artifactMutationRequested = false;
    bool dynamicLibraryLoadRequested = false;
    bool dynamicLibraryUnloadRequested = false;
    bool symbolResolutionRequested = false;
    bool sdxlApiRequested = false;
    bool bridgeCallRequested = false;
    bool serverConnectivityCheckRequested = false;
    bool walletLifecycleRequested = false;
    bool syncRequested = false;
    bool syncStatusPollingRequested = false;
    bool workerQueueRequested = false;
    bool walletStateMutationRequested = false;
    bool walletPersistenceRequested = false;
    bool uploadRequested = false;
    bool signingRequested = false;
    bool publicationRequested = false;
};

struct LiteBackendArtifactContractOptions {
    bool requireContractOwner = true;
    bool requireReadOnlyGate = true;
    bool requireImportedLibraryLinkMode = true;
    bool requireAbiVersion = true;
    bool requireSymbolInventory = true;
    bool requireAllRequiredSymbols = true;
    bool requireSignatureMetadataWhenRequired = true;
    bool validateOptionalSignatureMetadata = true;
    bool rejectRuntimeActions = true;
};

struct LiteBackendArtifactContractIssueInfo {
    LiteBackendArtifactContractIssue issue = LiteBackendArtifactContractIssue::ContractOwnerMissing;
    std::string message;
};

struct LiteBackendArtifactContractResult {
    bool ok = false;
    bool readOnlyContract = true;
    bool noArtifactMutation = true;
    bool noDynamicLibraryLoaded = true;
    bool noDynamicLibraryUnloaded = true;
    bool noSymbolResolutionPerformed = true;
    bool noSdxlCalls = true;
    bool noBridgeCalls = true;
    bool noServerConnectivityChecked = true;
    bool noWalletLifecycle = true;
    bool noSyncStarted = true;
    bool noSyncStatusPolled = true;
    bool noWorkerQueueEnqueue = true;
    bool noWalletStateMutation = true;
    bool noWalletPersistence = true;
    bool noUpload = true;
    bool noSigning = true;
    bool noPublication = true;

    bool contractOwnerAccepted = false;
    bool readOnlyGateAccepted = false;
    bool importedLinkModeAccepted = false;
    bool artifactPathAccepted = false;
    bool artifactKindAccepted = false;
    bool abiVersionAccepted = false;
    bool provenanceForwarded = false;
    bool signatureMetadataAccepted = false;
    bool signatureVerificationForwarded = false;
    bool signatureRequiredForRelease = false;
    bool signatureVerified = false;
    bool sdxlCompatibilityForwarded = false;
    bool symbolInventoryAccepted = false;
    bool requiredSymbolsAccepted = false;
    bool resolverInputProduced = false;
    bool dynamicLibraryLoadAllowed = false;
    bool symbolResolutionAllowed = false;
    bool runtimeActivationAllowed = false;

    std::size_t requiredSymbolCount = 0;
    std::size_t exportedSymbolCount = 0;
    LiteBackendArtifactContractStatus status = LiteBackendArtifactContractStatus::WaitingForContractOwner;
    LiteWalletSdxlArtifactSymbolsInput symbols;
    LiteBackendArtifactCandidate resolverCandidate;
    LiteBackendArtifactResolverInput resolverInput;
    std::vector<std::string> missingSymbols;
    std::vector<LiteBackendArtifactContractIssueInfo> issues;
    std::string error;
    std::string summary;
};

const char* liteBackendArtifactContractSupportedAbiVersion();
const char* liteBackendArtifactContractLinkModeName(LiteBackendArtifactContractLinkMode linkMode);
const char* liteBackendArtifactContractStatusName(LiteBackendArtifactContractStatus status);
const char* liteBackendArtifactContractIssueName(LiteBackendArtifactContractIssue issue);

std::vector<LiteBackendArtifactContractSymbol> liteBackendArtifactContractRequiredSymbols();
LiteWalletSdxlArtifactSymbolsInput liteBackendArtifactSymbolsFromExportedNames(
    const std::vector<std::string>& exportedSymbols);
LiteBackendArtifactContractResult evaluateLiteBackendArtifactContract(
    const LiteBackendArtifactContractInput& input,
    LiteBackendArtifactContractOptions options = {});
LiteBackendArtifactResolverInput liteBackendArtifactResolverInputFromContractResult(
    const LiteBackendArtifactContractResult& result);

} // namespace dragonx::wallet