#pragma once

#include "lite_connection_service.h"
#include "lite_wallet_sync_execution_readiness.h"

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

namespace dragonx::wallet {

enum class LiteBackendArtifactPlatform {
    Current,
    Linux,
    Windows,
    MacOS,
    Unknown,
};

enum class LiteBackendArtifactKind {
    Unknown,
    StaticLibrary,
    SharedLibrary,
    Executable,
};

enum class LiteBackendArtifactResolverStatus {
    ReadyForActivationReadiness,
    WaitingForResolverOwner,
    WaitingForReadOnlyGate,
    WaitingForArtifactSearchRoot,
    WaitingForArtifactCandidate,
    WaitingForArtifactMetadata,
    RuntimeActionDisabled,
};

enum class LiteBackendArtifactResolverIssue {
    ResolverOwnerMissing,
    ReadOnlyGateMissing,
    ArtifactSearchRootMissing,
    ArtifactSearchRootNotConfigured,
    ArtifactSearchRootNotDirectory,
    ArtifactCandidateMissing,
    ArtifactCandidateNotConfigured,
    ArtifactPathMissing,
    ArtifactMissing,
    ArtifactNotRegularFile,
    ArtifactUnreadable,
    UnsupportedArtifactKind,
    PlatformMismatch,
    VersionMissing,
    ProvenanceOwnerMissing,
    ProvenanceMetadataMissing,
    ArtifactNotSdxlCompatible,
    ArtifactSymbolsMissing,
    ArtifactStringOwnershipUnverified,
    ArtifactShutdownUnavailable,
    ExecutableMetadataMissing,
    ArtifactMutationRequested,
    SdxlApiRequested,
    ServerConnectivityCheckRequested,
    WalletLifecycleRequested,
    SyncRequested,
    SyncStatusPollingRequested,
    WorkerQueueRequested,
    WalletStateMutationRequested,
    WalletPersistenceRequested,
    UploadRequested,
    SigningRequested,
    PublicationRequested,
};

struct LiteBackendArtifactProvenanceMetadata {
    bool ownerReady = false;
    bool metadataProvided = false;
    std::string source;
    std::string builder;
    std::string sourceRevision;
    std::string artifactSetId;
    bool redacted = true;
};

struct LiteBackendArtifactSignatureVerificationMetadata {
    bool policyDefined = false;
    bool requiredForRelease = false;
    bool metadataProvided = false;
    bool verificationPerformed = false;
    bool verified = false;
    std::string signatureFormat;
    std::string signaturePath;
    std::string signatureFileSha256;
    std::string verificationTool;
    std::string verificationCommand;
    std::string keyFingerprint;
    std::string certificateIdentity;
    std::string certificateIssuer;
    std::string transparencyLogUrl;
    std::string verifiedArtifactSha256;
};

struct LiteBackendArtifactCandidate {
    bool configured = false;
    std::string artifactPath;
    LiteBackendArtifactPlatform platform = LiteBackendArtifactPlatform::Current;
    LiteBackendArtifactKind kind = LiteBackendArtifactKind::Unknown;
    std::string versionLabel;
    LiteBackendArtifactProvenanceMetadata provenance;
    LiteBackendArtifactSignatureVerificationMetadata signatureVerification;
    bool sdxlCompatible = false;
    LiteWalletSdxlArtifactSymbolsInput symbols;
    bool executableMetadataRequired = false;
};

struct LiteBackendArtifactSearchRoot {
    bool configured = false;
    std::string rootPath;
    LiteBackendArtifactPlatform platform = LiteBackendArtifactPlatform::Current;
    LiteBackendArtifactKind kind = LiteBackendArtifactKind::Unknown;
    std::string versionLabel;
    LiteBackendArtifactProvenanceMetadata provenance;
    LiteBackendArtifactSignatureVerificationMetadata signatureVerification;
    bool sdxlCompatible = false;
    LiteWalletSdxlArtifactSymbolsInput symbols;
    bool executableMetadataRequired = false;
    std::vector<std::string> expectedArtifactNames;
};

struct LiteBackendArtifactResolverInput {
    bool resolverOwnerReady = false;
    bool readOnlyGateReady = false;
    std::string projectRoot;
    LiteBackendArtifactPlatform expectedPlatform = LiteBackendArtifactPlatform::Current;
    std::vector<LiteBackendArtifactSearchRoot> searchRoots;
    std::vector<LiteBackendArtifactCandidate> candidates;

    bool artifactMutationRequested = false;
    bool sdxlApiRequested = 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 LiteBackendArtifactResolverOptions {
    bool requireResolverOwner = true;
    bool requireReadOnlyGate = true;
    bool requireArtifactCandidates = true;
    bool requireVersionMetadata = true;
    bool requireProvenanceMetadata = true;
    bool requireSdxlCompatibility = true;
    bool requireSdxlSymbols = true;
    bool rejectArtifactMutation = true;
    bool rejectSdxlApiCalls = true;
    bool rejectServerConnectivityChecks = true;
    bool rejectWalletLifecycle = true;
    bool rejectSync = true;
    bool rejectSyncStatusPolling = true;
    bool rejectWorkerQueue = true;
    bool rejectWalletStateMutation = true;
    bool rejectWalletPersistence = true;
    bool rejectUpload = true;
    bool rejectSigning = true;
    bool rejectPublication = true;
};

struct LiteBackendResolvedArtifact {
    bool found = false;
    std::string artifactPath;
    LiteBackendArtifactPlatform platform = LiteBackendArtifactPlatform::Unknown;
    LiteBackendArtifactKind kind = LiteBackendArtifactKind::Unknown;
    std::string versionLabel;
    LiteBackendArtifactProvenanceMetadata provenance;
    LiteBackendArtifactSignatureVerificationMetadata signatureVerification;
    bool exists = false;
    bool regularFile = false;
    bool readable = false;
    bool executable = false;
    bool sdxlCompatible = false;
    LiteWalletSdxlArtifactSymbolsInput symbols;
    std::size_t artifactSizeBytes = 0;
};

struct LiteBackendArtifactResolverIssueInfo {
    LiteBackendArtifactResolverIssue issue = LiteBackendArtifactResolverIssue::ArtifactCandidateMissing;
    std::string message;
};

struct LiteBackendArtifactResolverResult {
    bool ok = false;
    bool readOnlyArtifactDiscovery = true;
    bool artifactMetadataReadOnly = true;
    bool provenanceReadOnly = true;
    bool executableMetadataReadOnly = true;
    bool noArtifactMutation = true;
    bool noSdxlCalls = true;
    bool noServerConnectivityChecked = true;
    bool noWalletCreated = true;
    bool noWalletOpened = true;
    bool noWalletRestored = 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 resolverOwnerAccepted = false;
    bool readOnlyGateAccepted = false;
    bool artifactSearchRootsAccepted = false;
    bool artifactCandidatesAccepted = false;
    bool artifactDiscovered = false;
    bool artifactMetadataAccepted = false;
    bool platformAccepted = false;
    bool versionAccepted = false;
    bool provenanceAccepted = false;
    bool sdxlCompatibilityAccepted = false;
    bool symbolMetadataAccepted = false;
    bool executableMetadataAccepted = false;
    bool syncArtifactInputProduced = false;

    std::size_t searchRootCount = 0;
    std::size_t candidateCount = 0;
    std::size_t checkedCandidateCount = 0;
    std::size_t rejectedCandidateCount = 0;

    LiteBackendArtifactResolverStatus status = LiteBackendArtifactResolverStatus::WaitingForResolverOwner;
    LiteBackendResolvedArtifact artifact;
    LiteWalletSdxlArtifactInput syncArtifactInput;
    std::vector<LiteBackendArtifactResolverIssueInfo> issues;
    std::string error;
};

enum class LiteBackendActivationReadinessStatus {
    ReadyForConnectionReadiness,
    WaitingForActivationOwner,
    WaitingForReadOnlyGate,
    WaitingForLiteBuild,
    WaitingForBackendCapability,
    WaitingForArtifactResolver,
    WaitingForBackendLink,
    WaitingForBridge,
    WaitingForConnectionSettings,
    RuntimeActionDisabled,
};

enum class LiteBackendActivationReadinessIssue {
    ActivationOwnerMissing,
    ReadOnlyGateMissing,
    FullNodeBuild,
    LiteBackendCapabilityMissing,
    ArtifactResolverRejected,
    BackendNotLinked,
    BridgeUnavailable,
    ConnectionSettingsRejected,
    ArtifactMutationRequested,
    SdxlApiRequested,
    ServerConnectivityCheckRequested,
    WalletLifecycleRequested,
    SyncRequested,
    SyncStatusPollingRequested,
    WorkerQueueRequested,
    WalletStateMutationRequested,
    WalletPersistenceRequested,
    UploadRequested,
    SigningRequested,
    PublicationRequested,
};

struct LiteBackendBridgeReadinessInput {
    bool linked = false;
    bool bridgeAvailable = false;
    WalletBackendStatus status;
    std::string bridgeUnavailableReason;
};

struct LiteBackendActivationReadinessInput {
    WalletCapabilities capabilities;
    LiteConnectionSettings connectionSettings;
    LiteBackendArtifactResolverInput artifactResolver;
    LiteBackendBridgeReadinessInput backend;
    bool activationOwnerReady = false;
    bool readOnlyGateReady = false;

    bool artifactMutationRequested = false;
    bool sdxlApiRequested = 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 LiteBackendActivationReadinessOptions {
    bool requireActivationOwner = true;
    bool requireReadOnlyGate = true;
    bool requireLiteBuild = true;
    bool requireLiteBackendCapability = true;
    bool requireResolvedArtifact = true;
    bool requireLinkedBackend = true;
    bool requireBridgeAvailable = true;
    bool requireUsableServer = true;
    bool rejectArtifactMutation = true;
    bool rejectSdxlApiCalls = true;
    bool rejectServerConnectivityChecks = true;
    bool rejectWalletLifecycle = true;
    bool rejectSync = true;
    bool rejectSyncStatusPolling = true;
    bool rejectWorkerQueue = true;
    bool rejectWalletStateMutation = true;
    bool rejectWalletPersistence = true;
    bool rejectUpload = true;
    bool rejectSigning = true;
    bool rejectPublication = true;
    LiteBackendArtifactResolverOptions resolverOptions;
};

struct LiteBackendActivationReadinessIssueInfo {
    LiteBackendActivationReadinessIssue issue = LiteBackendActivationReadinessIssue::ActivationOwnerMissing;
    std::string message;
};

struct LiteBackendActivationReadinessResult {
    bool ok = false;
    bool readOnlyActivation = true;
    bool artifactDiscoveryReadOnly = true;
    bool connectionReadinessOnly = true;
    bool noBridgeCalls = true;
    bool noArtifactMutation = true;
    bool noSdxlCalls = true;
    bool noServerConnectivityChecked = true;
    bool noWalletCreated = true;
    bool noWalletOpened = true;
    bool noWalletRestored = 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 activationOwnerAccepted = false;
    bool readOnlyGateAccepted = false;
    bool liteBuildAccepted = false;
    bool backendCapabilityAccepted = false;
    bool artifactResolverAccepted = false;
    bool backendLinkedAccepted = false;
    bool bridgeAccepted = false;
    bool connectionSettingsAccepted = false;
    bool connectionServiceBoundaryAccepted = false;
    bool syncReadinessInputsProduced = false;

    LiteBackendActivationReadinessStatus status = LiteBackendActivationReadinessStatus::WaitingForActivationOwner;
    LiteBackendArtifactResolverResult artifactResolverResult;
    LiteWalletSdxlArtifactInput syncArtifactInput;
    LiteWalletLinkedBackendReadinessInput syncBackendInput;
    LiteConnectionAvailability connectionAvailability = LiteConnectionAvailability::BackendUnavailable;
    LiteServerSelectionResult selectedServer;
    WalletBackendStatus connectionStatus;
    std::vector<LiteBackendActivationReadinessIssueInfo> issues;
    std::string error;
};

LiteBackendArtifactPlatform currentLiteBackendArtifactPlatform();
const char* liteBackendArtifactPlatformName(LiteBackendArtifactPlatform platform);
const char* liteBackendArtifactKindName(LiteBackendArtifactKind kind);
const char* liteBackendArtifactResolverStatusName(LiteBackendArtifactResolverStatus status);
const char* liteBackendArtifactResolverIssueName(LiteBackendArtifactResolverIssue issue);
const char* liteBackendActivationReadinessStatusName(LiteBackendActivationReadinessStatus status);
const char* liteBackendActivationReadinessIssueName(LiteBackendActivationReadinessIssue issue);

LiteBackendArtifactResolverResult evaluateLiteBackendArtifactResolver(
    const LiteBackendArtifactResolverInput& input,
    LiteBackendArtifactResolverOptions options = {});

LiteBackendActivationReadinessResult evaluateLiteBackendActivationReadiness(
    const LiteBackendActivationReadinessInput& input,
    LiteBackendActivationReadinessOptions options = {});

class LiteBackendArtifactResolver {
public:
    explicit LiteBackendArtifactResolver(LiteBackendArtifactResolverOptions options = {});

    LiteBackendArtifactResolverResult resolve(const LiteBackendArtifactResolverInput& input) const;

private:
    LiteBackendArtifactResolverOptions options_;
};

class LiteBackendActivationReadinessAdapter {
public:
    explicit LiteBackendActivationReadinessAdapter(LiteBackendActivationReadinessOptions options = {});

    LiteBackendActivationReadinessResult evaluate(const LiteBackendActivationReadinessInput& input) const;

private:
    LiteBackendActivationReadinessOptions options_;
};

} // namespace dragonx::wallet
