#!/usr/bin/env node
import {
  atomicWriteFile
} from "./chunk-TAEQKBJB.mjs";
import {
  ensureDir,
  exists,
  readJsonFile
} from "./chunk-IAYRNVUC.mjs";
import {
  PROJECT_CONFIG_FILE,
  PROJECT_DIR_NAME,
  PROJECT_STATE_FILE
} from "./chunk-H76MT5UR.mjs";

// src/build-target.ts
var injectedBuildChannel = true ? "development" : void 0;
var BUILD_CHANNEL = injectedBuildChannel === "published" ? "published" : "development";
var IS_PUBLISHED_BUILD = BUILD_CHANNEL === "published";
var PUBLISHED_ENVIRONMENT = "prod";

// src/config/project-config.ts
import path from "path";
var LEGACY_DEFAULT_DEPLOYMENT_ID = "legacy";
var LEGACY_DEFAULT_OWNER_SCOPE_ID = "default";
var LEGACY_DEFAULT_BINDING_KEY = `${LEGACY_DEFAULT_DEPLOYMENT_ID}:${LEGACY_DEFAULT_OWNER_SCOPE_ID}`;
function normalizeProjectManifest(config) {
  return {
    schemaVersion: 2,
    projectId: config.projectId,
    slug: config.slug
  };
}
function normalizeProjectBinding(config) {
  return {
    deploymentId: config.deploymentId ?? LEGACY_DEFAULT_DEPLOYMENT_ID,
    ownerScopeId: config.ownerScopeId ?? LEGACY_DEFAULT_OWNER_SCOPE_ID,
    gameId: config.gameId,
    remoteHeadDigest: config.remoteHeadDigest,
    jobId: config.jobId,
    agentManaged: config.agentManaged,
    workspacePrepared: config.workspacePrepared,
    allowCreateGame: config.allowCreateGame,
    environment: config.environment,
    authoring: config.authoring,
    compile: config.compile,
    localMaintainerRegistry: config.localMaintainerRegistry,
    apiBaseUrl: config.apiBaseUrl,
    webBaseUrl: config.webBaseUrl,
    packageManifest: config.packageManifest,
    environmentManifest: config.environmentManifest
  };
}
function normalizeProjectState(config, existing) {
  const binding = normalizeProjectBinding(config);
  const bindingKey = config.bindingKey || `${binding.deploymentId}:${binding.ownerScopeId}`;
  return {
    schemaVersion: 1,
    bindings: {
      ...existing?.bindings ?? {},
      [bindingKey]: binding
    }
  };
}
function mergeManifestAndBinding(manifest, binding, bindingKey) {
  return {
    ...manifest,
    ...binding ?? {
      deploymentId: LEGACY_DEFAULT_DEPLOYMENT_ID,
      ownerScopeId: LEGACY_DEFAULT_OWNER_SCOPE_ID
    },
    gameId: binding?.gameId ?? manifest.projectId,
    bindingKey: bindingKey ?? `${binding?.deploymentId ?? LEGACY_DEFAULT_DEPLOYMENT_ID}:${binding?.ownerScopeId ?? LEGACY_DEFAULT_OWNER_SCOPE_ID}`
  };
}
function isProjectManifestV2(value) {
  const candidate = value;
  return candidate?.schemaVersion === 2 && typeof candidate.projectId === "string" && typeof candidate.slug === "string";
}
function normalizeLegacyProjectConfig(config) {
  return {
    schemaVersion: 2,
    projectId: config.projectId ?? config.gameId,
    slug: config.slug,
    bindingKey: LEGACY_DEFAULT_BINDING_KEY,
    deploymentId: LEGACY_DEFAULT_DEPLOYMENT_ID,
    ownerScopeId: LEGACY_DEFAULT_OWNER_SCOPE_ID,
    gameId: config.gameId,
    jobId: config.jobId,
    agentManaged: config.agentManaged,
    workspacePrepared: config.workspacePrepared,
    allowCreateGame: config.allowCreateGame,
    environment: config.environment,
    authoring: config.authoring,
    compile: config.compile,
    localMaintainerRegistry: config.localMaintainerRegistry,
    apiBaseUrl: config.apiBaseUrl,
    webBaseUrl: config.webBaseUrl,
    packageManifest: config.packageManifest,
    environmentManifest: config.environmentManifest
  };
}
async function loadProjectEnvironmentState(rootDir) {
  const filePath = path.join(rootDir, PROJECT_DIR_NAME, PROJECT_STATE_FILE);
  if (!await exists(filePath)) {
    return { schemaVersion: 1, bindings: {} };
  }
  const state = await readJsonFile(filePath);
  return state.schemaVersion === 1 && state.bindings ? state : { schemaVersion: 1, bindings: {} };
}
async function loadProjectConfig(rootDir) {
  const filePath = path.join(rootDir, PROJECT_DIR_NAME, PROJECT_CONFIG_FILE);
  const rawConfig = await readJsonFile(
    filePath
  );
  if (!isProjectManifestV2(rawConfig)) {
    const migrated = normalizeLegacyProjectConfig(
      rawConfig
    );
    await updateProjectState(rootDir, migrated);
    return migrated;
  }
  const state = await loadProjectEnvironmentState(rootDir);
  const entries = Object.entries(state.bindings);
  const [bindingKey, binding] = entries.find(([key]) => key !== LEGACY_DEFAULT_BINDING_KEY) ?? entries.find(([key]) => key === LEGACY_DEFAULT_BINDING_KEY) ?? [];
  return mergeManifestAndBinding(rawConfig, binding, bindingKey);
}
async function updateProjectState(rootDir, config) {
  const dir = path.join(rootDir, PROJECT_DIR_NAME);
  await ensureDir(dir);
  const existingState = await loadProjectEnvironmentState(rootDir);
  await atomicWriteFile(
    path.join(dir, PROJECT_CONFIG_FILE),
    `${JSON.stringify(normalizeProjectManifest(config), null, 2)}
`,
    { mode: 420 }
  );
  await atomicWriteFile(
    path.join(dir, PROJECT_STATE_FILE),
    `${JSON.stringify(normalizeProjectState(config, existingState), null, 2)}
`,
    { mode: 384 }
  );
}
async function findProjectRoot(startDir) {
  let current = path.resolve(startDir);
  for (let i = 0; i < 25; i++) {
    const candidate = path.join(current, PROJECT_DIR_NAME, PROJECT_CONFIG_FILE);
    if (await exists(candidate)) {
      return current;
    }
    const parent = path.dirname(current);
    if (parent === current) break;
    current = parent;
  }
  return null;
}

export {
  BUILD_CHANNEL,
  IS_PUBLISHED_BUILD,
  PUBLISHED_ENVIRONMENT,
  loadProjectConfig,
  updateProjectState,
  findProjectRoot
};
//# sourceMappingURL=chunk-776W3UGV.mjs.map