export interface IInstanceBootstrapSecretRef {
  readonly name: string;
  readonly provider: string;
  readonly ref: string;
  readonly required?: boolean;
}

export interface IInstanceBootstrapDescriptor {
  readonly id: string;
  readonly packageName: string;
  readonly packageRevision?: string;
  readonly class: string;
  readonly mount?: string;
  readonly rootKind: string;
  readonly componentType?: string;
  readonly configRef?: string;
  readonly secretRefs?: ReadonlyArray<IInstanceBootstrapSecretRef>;
  readonly dependsOn?: ReadonlyArray<string>;
  readonly policyRef?: string;
  readonly autoStart?: boolean;
  readonly registrationSource: string;
}

export interface IAliasedInstanceBootstrapContext<
  TDescriptor extends IInstanceBootstrapDescriptor = IInstanceBootstrapDescriptor,
> {
  readonly instance: TDescriptor;
  readonly serviceInstance: TDescriptor;
  readonly deploymentInstance: TDescriptor;
}

export interface IMountedInstanceBootstrapProps<
  TDescriptor extends IInstanceBootstrapDescriptor = IInstanceBootstrapDescriptor,
> extends IAliasedInstanceBootstrapContext<TDescriptor> {
  readonly effectiveConfig: Record<string, unknown>;
  readonly dependsOn?: ReadonlyArray<string>;
  readonly secretRefs?: ReadonlyArray<IInstanceBootstrapSecretRef>;
}

export function buildInstanceBootstrapDescriptor<
  TDescriptor extends IInstanceBootstrapDescriptor,
>(descriptor: TDescriptor): TDescriptor {
  const normalized = {
    id: descriptor.id,
    packageName: descriptor.packageName,
    ...(descriptor.packageRevision ? { packageRevision: descriptor.packageRevision } : {}),
    class: descriptor.class,
    ...(descriptor.mount ? { mount: descriptor.mount } : {}),
    rootKind: descriptor.rootKind,
    ...(descriptor.componentType ? { componentType: descriptor.componentType } : {}),
    ...(descriptor.configRef ? { configRef: descriptor.configRef } : {}),
    ...(descriptor.secretRefs?.length ? { secretRefs: structuredClone(descriptor.secretRefs) } : {}),
    ...(descriptor.dependsOn?.length ? { dependsOn: [...descriptor.dependsOn] } : {}),
    ...(descriptor.policyRef ? { policyRef: descriptor.policyRef } : {}),
    ...(descriptor.autoStart === true ? { autoStart: true } : {}),
    registrationSource: descriptor.registrationSource,
  };
  return normalized as TDescriptor;
}

export function buildAliasedInstanceBootstrapContext<
  TDescriptor extends IInstanceBootstrapDescriptor,
>(descriptor: TDescriptor): IAliasedInstanceBootstrapContext<TDescriptor> {
  const instance = buildInstanceBootstrapDescriptor(descriptor);
  return {
    instance,
    serviceInstance: structuredClone(instance),
    deploymentInstance: structuredClone(instance),
  };
}

export function buildMountedInstanceBootstrapProps<
  TDescriptor extends IInstanceBootstrapDescriptor,
>(
  descriptor: TDescriptor,
  effectiveConfig: Record<string, unknown> = {},
): IMountedInstanceBootstrapProps<TDescriptor> {
  const { instance, serviceInstance, deploymentInstance } = buildAliasedInstanceBootstrapContext(descriptor);
  return {
    instance,
    serviceInstance,
    deploymentInstance,
    effectiveConfig: structuredClone(effectiveConfig),
    ...(instance.dependsOn?.length ? { dependsOn: [...instance.dependsOn] } : {}),
    ...(instance.secretRefs?.length ? { secretRefs: structuredClone(instance.secretRefs) } : {}),
  };
}
