import { Api as ApiPb } from '@superblocksteam/types';

import { AnyPageDSL, ApplicationConfiguration, ApplicationSettings } from '../types/index.js';

/** A signature, as produced by the agent. */
export interface Signature {
  /** The id of the key used to sign the data. */
  keyId: string;
  /** The actual signature, in base64. */
  data: string;
  /** The public key for the key used to sign the data, in base64. */
  publicKey?: string;
  /** The algorithm used to sign the data. */
  algorithm?: string;
}

interface VersionedDslHash {
  /** The version of the DSL. */
  version: number;
  /**
   * The SHA-256 hash of the DSL, in base64.
   * For pages, this is the hash of the actual page DSL, i.e. `page.layouts[0].dsl`.
   * */
  hash: string;
}

export interface ApplicationSettingsHashes {
  /** The SHA-256 hash of all custom components related properties from settings, in base64. */
  components: string;
  /** The SHA-256 hash of settings without the custom components related properties, in base64. */
  rest: string;
}

export interface ApplicationSignatureTreeV1 {
  /** The version of the signature tree. */
  v: 1;
  settings: ApplicationSettingsHashes;
  page: VersionedDslHash;
}

export interface ApplicationSignatureTreeV2 {
  /** The version of the signature tree. */
  v: 2;
  settings: ApplicationSettingsHashes;
  pages: Record<string, VersionedDslHash>;
  configuration: VersionedDslHash;
}

export type ApplicationSignatureTree = ApplicationSignatureTreeV1 | ApplicationSignatureTreeV2;

export interface ApplicationSignatureTreeSigned {
  /** The SHA-256 hash of `root`, in base64. */
  signature: Signature;
  root: ApplicationSignatureTree;
}

export type PageUpdate = {
  type: 'page';
  pageId: string;
  pageDsl: AnyPageDSL;
};

type PageDelete = {
  type: 'delete-page';
  pageId: string;
};

export type ConfigurationUpdate = {
  type: 'configuration';
  configuration: ApplicationConfiguration;
};

type SettingUpdate = {
  type: 'settings';
  settings: ApplicationSettings;
};

export type ApplicationSignatureTreeUpdate = PageUpdate | PageDelete | ConfigurationUpdate | SettingUpdate;

export type AppToSign = {
  rootHash: string;
};

export type AppToVerify = {
  rootHash: string;
  signature?: Signature;
};

export type ApiToSign = {
  apiPb: ApiPb;
};

export type ApiToVerify = {
  apiPb: ApiPb;
  signature?: Signature;
};
