import type { CredentialReferenceId } from "@awp/contracts";
import type { CandidateManifest } from "@awp/domain";

export interface GitHubRepositoryState {
  readonly repositoryKey: string;
  readonly nativeId: string;
  readonly defaultBranch: string;
  readonly headRevision: string;
  readonly url?: string;
}

export interface GitHubPublicationState {
  readonly nativeId: string;
  readonly repositoryKey: string;
  readonly targetRef: string;
  readonly targetRevision: string;
  readonly baseRevision: string;
  readonly candidateDigest: string;
  readonly candidateManifest: CandidateManifest;
  readonly factoryRunId: string;
  readonly idempotencyKey: string;
  readonly status: "published" | "missing" | "conflict";
  readonly url?: string;
}

export interface GitHubMergeState {
  readonly nativeId: string;
  readonly repositoryKey: string;
  readonly targetRef: string;
  readonly expectedTargetRevision: string;
  readonly expectedBaseRevision: string;
  readonly publicationNativeId: string;
  readonly candidateDigest: string;
  readonly candidateManifest: CandidateManifest;
  readonly resultingRevision: string;
  readonly status: "merged" | "missing" | "conflict";
  readonly url?: string;
}

export interface GitHubTrustedClient {
  inspectRepository(
    repositoryKey: string,
    credentialReferenceId: CredentialReferenceId,
  ): Promise<GitHubRepositoryState>;
  findPublicationByIdempotencyKey(input: {
    readonly repositoryKey: string;
    readonly targetRef: string;
    readonly idempotencyKey: string;
    readonly credentialReferenceId: CredentialReferenceId;
  }): Promise<GitHubPublicationState | undefined>;
  publishCandidate(input: {
    readonly repositoryKey: string;
    readonly targetRef: string;
    readonly expectedBaseRevision: string;
    readonly candidateDigest: string;
    readonly candidateManifest: CandidateManifest;
    readonly diff: string;
    readonly changeSetId: string;
    readonly factoryRunId: string;
    readonly idempotencyKey: string;
    readonly credentialReferenceId: CredentialReferenceId;
  }): Promise<GitHubPublicationState>;
  readPublication(
    nativeId: string,
    credentialReferenceId: CredentialReferenceId,
  ): Promise<GitHubPublicationState | undefined>;
  findMergeByIdempotencyKey(input: {
    readonly repositoryKey: string;
    readonly targetRef: string;
    readonly expectedTargetRevision: string;
    readonly expectedBaseRevision: string;
    readonly publicationNativeId: string;
    readonly candidateDigest: string;
    readonly candidateManifest: CandidateManifest;
    readonly idempotencyKey: string;
    readonly credentialReferenceId: CredentialReferenceId;
  }): Promise<GitHubMergeState | undefined>;
  mergePublication(input: {
    readonly repositoryKey: string;
    readonly targetRef: string;
    readonly expectedTargetRevision: string;
    readonly expectedBaseRevision: string;
    readonly publicationNativeId: string;
    readonly candidateDigest: string;
    readonly candidateManifest: CandidateManifest;
    readonly idempotencyKey: string;
    readonly credentialReferenceId: CredentialReferenceId;
  }): Promise<GitHubMergeState>;
  readMerge(
    nativeId: string,
    credentialReferenceId: CredentialReferenceId,
  ): Promise<GitHubMergeState | undefined>;
}
