import {
  ECRClient
} from "./chunk-50jpda9q.js";
import {
  collectPhpAppEntries,
  generateAppImageDockerfile,
  packageServerlessApp,
  phpRuntimeLayerAssets,
  runPhpBuildHooks,
  sha256
} from "./chunk-tq46tnxv.js";

// src/deploy/serverless-image.ts
import { execFileSync } from "node:child_process";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";

// src/utils/cli.ts
var colors = {
  reset: "\x1B[0m",
  bright: "\x1B[1m",
  dim: "\x1B[2m",
  red: "\x1B[31m",
  green: "\x1B[32m",
  yellow: "\x1B[33m",
  blue: "\x1B[34m",
  magenta: "\x1B[35m",
  cyan: "\x1B[36m",
  white: "\x1B[37m",
  gray: "\x1B[90m"
};
function colorize(text, color) {
  return `${colors[color]}${text}${colors.reset}`;
}
function success(message) {
  console.log(`${colors.green}✓${colors.reset} ${message}`);
}
function error(message) {
  console.error(`${colors.red}✗${colors.reset} ${message}`);
}
function warn(message) {
  console.warn(`${colors.yellow}⚠${colors.reset} ${message}`);
}
function info(message) {
  console.log(`${colors.blue}ℹ${colors.reset} ${message}`);
}
function step(message) {
  console.log(`${colors.cyan}→${colors.reset} ${message}`);
}
function header(message) {
  console.log(`
${colors.bright}${colors.cyan}${message}${colors.reset}
`);
}
var isCI = !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.BUILDKITE || process.env.CIRCLECI || process.env.GITLAB_CI);
function box(message, color = "cyan") {
  const lines = message.split(`
`);
  const maxLength = Math.max(...lines.map((line) => line.length));
  const border = "─".repeat(maxLength + 2);
  console.log(colorize(`┌${border}┐`, color));
  lines.forEach((line) => {
    console.log(colorize(`│ ${line.padEnd(maxLength)} │`, color));
  });
  console.log(colorize(`└${border}┘`, color));
}

// src/deploy/serverless-image.ts
function writeEntries(baseDir, entries) {
  for (const e of entries) {
    const dest = join(baseDir, e.name);
    mkdirSync(dirname(dest), { recursive: true });
    writeFileSync(dest, e.data, e.mode ? { mode: e.mode } : undefined);
  }
}
async function buildAndPushServerlessImage(opts) {
  const { app, projectRoot, region, repository } = opts;
  const arch = app.architecture ?? "x86_64";
  const platform = arch === "arm64" ? "linux/arm64" : "linux/amd64";
  const isPhp = app.kind === "php";
  const step2 = opts.onStep ?? (() => {});
  const stage = mkdtempSync(join(tmpdir(), "tscloud-img-"));
  try {
    const appDir = join(stage, "app");
    mkdirSync(appDir, { recursive: true });
    let handlers;
    let contentHash;
    if (isPhp) {
      runPhpBuildHooks({ projectRoot, app, skipBuild: opts.skipBuild, onStep: step2 });
      step2("staging application tree");
      const entries = collectPhpAppEntries(projectRoot);
      writeEntries(appDir, entries);
      writeEntries(join(stage, "runtime"), phpRuntimeLayerAssets().map((a) => ({ name: a.path, data: a.contents, mode: a.mode })));
      const handler = app.handlers?.http ?? "public/index.php";
      handlers = { http: handler, queue: app.handlers?.queue ?? handler, cli: app.handlers?.cli ?? handler };
      contentHash = sha256(entries.map((e) => `${e.name}:${e.data.length}`).join("|"));
    } else {
      step2("bundling application");
      const artifact = await packageServerlessApp({ projectRoot, app, skipBuild: opts.skipBuild, onStep: step2 });
      writeFileSync(join(appDir, "index.mjs"), artifact.bundle);
      handlers = artifact.handlers;
      contentHash = artifact.sha256;
    }
    const tag = contentHash.slice(0, 16);
    writeFileSync(join(stage, "Dockerfile"), generateAppImageDockerfile({
      kind: app.kind ?? "node",
      phpVersion: app.phpVersion,
      architecture: arch
    }));
    const ecr = new ECRClient(region);
    let repoUri;
    try {
      const desc = await ecr.describeRepositories({ repositoryNames: [repository] });
      repoUri = desc.repositories?.[0]?.repositoryUri ?? "";
    } catch {
      repoUri = "";
    }
    if (!repoUri) {
      step2(`creating ECR repository ${repository}`);
      const created = await ecr.createRepository({
        repositoryName: repository,
        imageScanningConfiguration: { scanOnPush: true }
      });
      repoUri = created.repository?.repositoryUri ?? "";
    }
    if (!repoUri)
      throw new Error(`could not resolve ECR repository URI for ${repository}`);
    const imageUri = `${repoUri}:${tag}`;
    step2("docker build");
    execFileSync("docker", ["build", "--platform", platform, "--provenance=false", "--sbom=false", "-t", imageUri, stage], { stdio: "inherit" });
    step2("ecr auth + push");
    const auth = await ecr.getAuthorizationToken();
    const data = auth.authorizationData?.[0];
    if (!data?.authorizationToken || !data.proxyEndpoint)
      throw new Error("failed to get an ECR authorization token");
    const registry = data.proxyEndpoint.replace(/^https?:\/\//, "");
    const dockerConfig = join(stage, ".docker");
    mkdirSync(dockerConfig, { recursive: true });
    writeFileSync(join(dockerConfig, "config.json"), JSON.stringify({ auths: { [registry]: { auth: data.authorizationToken } } }));
    execFileSync("docker", ["push", imageUri], {
      stdio: "inherit",
      env: { ...process.env, DOCKER_CONFIG: dockerConfig }
    });
    info(`Image: ${imageUri}`);
    return { imageUri, tag, handlers };
  } finally {
    rmSync(stage, { recursive: true, force: true });
  }
}

export { success, error, warn, info, step, header, box, buildAndPushServerlessImage };
