export function requiredEnvironment(
  environment: Readonly<Record<string, string | undefined>>,
  name: string,
): string {
  const value = environment[name]?.trim();
  if (!value) throw new Error(`${name} is required`);
  return value;
}

export interface OwnerCreatedJourneyEnvironment {
  readonly projectId: string;
  readonly planId: string;
  readonly planRevisionId: string;
  readonly taskIds: readonly [string, string, string];
}

function orderedTaskIds(
  environment: Readonly<Record<string, string | undefined>>,
): readonly [string, string, string] {
  const taskIds = requiredEnvironment(environment, "AWP_TASK_IDS")
    .split(",")
    .map((value) => value.trim())
    .filter(Boolean);
  if (taskIds.length !== 3 || new Set(taskIds).size !== 3) {
    throw new Error("AWP_TASK_IDS must contain exactly three unique ordered Task IDs");
  }
  return taskIds as [string, string, string];
}

export function ownerCreatedJourneyEnvironment(
  environment: Readonly<Record<string, string | undefined>> = process.env,
): OwnerCreatedJourneyEnvironment {
  return {
    projectId: requiredEnvironment(environment, "AWP_PROJECT_ID"),
    planId: requiredEnvironment(environment, "AWP_PLAN_ID"),
    planRevisionId: requiredEnvironment(environment, "AWP_PLAN_REVISION_ID"),
    taskIds: orderedTaskIds(environment),
  };
}

export interface ApprovedJourneyEnvironment extends OwnerCreatedJourneyEnvironment {
  readonly firstTaskId: string;
  readonly factoryRunId: string;
}

export function approvedJourneyEnvironment(
  environment: Readonly<Record<string, string | undefined>> = process.env,
): ApprovedJourneyEnvironment {
  const ownerCreated = ownerCreatedJourneyEnvironment(environment);
  const factoryRunId = requiredEnvironment(environment, "AWP_FACTORY_RUN_ID");
  const firstTaskId = requiredEnvironment(environment, "AWP_FIRST_TASK_ID");
  if (ownerCreated.taskIds[0] !== firstTaskId) {
    throw new Error("AWP_FIRST_TASK_ID must equal the first ordered AWP_TASK_IDS value");
  }
  return { ...ownerCreated, firstTaskId, factoryRunId };
}

export function sqlLiteral(value: string): string {
  return `'${value.replaceAll("'", "''")}'`;
}
