/**
 * {{titleCase name}} — Pulumi app definition
 *
 * Pattern: getConfig → AppEnvironment → primitives → services → register
 */

import * as pulumi from "@pulumi/pulumi";
import * as path from "node:path";
import { fileURLToPath } from "node:url";
import { mesh } from "@mesh-tech/app-kit/infra";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const { tenant, platform, stack, deploy } = mesh.apps.getConfig(pulumi);
{{#if temporal}}

const TASK_QUEUE = "{{name}}";
{{/if}}

// =============================================================================
// Environment
// =============================================================================

const env = new mesh.apps.AppEnvironment("env", {
  tenant,
  platform,
  stack,
  deploy,
  appName: "{{name}}",
  namespace: true,
  rootDir: __dirname,
{{#if temporal}}
  temporal: {
    codecServer: {
      ingressSubdomain: "codec-{{name}}",
    },
  },
{{/if}}
});

// =============================================================================
// Primitives
// =============================================================================
{{#if database}}

const db = new mesh.apps.Database("db", { env });
{{/if}}
{{#if bucket}}

const uploads = new mesh.apps.Bucket("uploads", {
  env,
  forceDestroy: stack !== "prod",
});
{{/if}}

// =============================================================================
// Services
// =============================================================================
{{#if service}}

const api = new mesh.apps.Service("api", {
  env,
  title: "{{titleCase name}} API",
  description: "HTTP API for {{titleCase name}}",
  runtime: "node",
  src: "./api",
  port: 3000,
  link: [
{{#if database}}
    db.link({ environmentPrefix: "DATABASE" }),
{{/if}}
{{#if bucket}}
    uploads.link({ environmentPrefix: "UPLOADS", access: "readWrite" }),
{{/if}}
{{#if temporal}}
    env.temporal!.link({ environmentPrefix: "TEMPORAL", taskQueue: TASK_QUEUE }),
{{/if}}
  ],
  ingress: env.buildIngress({
    subdomain: "{{name}}",
    healthCheckPath: "/health",
  }),
  healthCheck: "/health",
  replicas: deploy ? 2 : 1,
  resources: { cpu: "100m", memory: "128Mi" },
});
{{/if}}
{{#if temporal}}

const worker = new mesh.apps.TemporalWorker("worker", {
  env,
  title: "{{titleCase name}} Worker",
  description: "Temporal workflow worker for {{titleCase name}}",
  runtime: "node",
  src: "./worker",
  taskQueue: TASK_QUEUE,
  replicas: 1,
  resources: { cpu: "100m", memory: "256Mi" },
});
{{/if}}

{{#if service}}

// =============================================================================
// Docs — the API's reference site, built by the platform from the spec and
// the guides in docs/pages/ (this README is its landing page — `landingPage`
// names another file, or `false` — and every guide is listed after it, in
// path order). A docs site has no hostname of its own: here it
// is reachable under `mesh dev`, and it is published by being read inside
// the Hub. To publish it, declare the API as a `mesh.apps.AppApiSurface`
// whose `docs` block builds this same site (`docs: { spec, pages }`) — the
// Hub then serves it through its docs door. Its readers hold this app's
// `docs` project role: declare the role on the ZitadelAppIdentity and grant
// it from Access → People; that same role is what the Hub reads when a
// partner holding the Hub's `docs:<tenant>` role opens this app's Docs tab,
// and the app then appears in their Apps list. `mesh app check` flags a docs
// site put on an ingress instead (`DOCS_SITE_PUBLIC`).
// =============================================================================

new mesh.apps.ApiDocs("docs", {
  env,
  sources: { openapi: "./api/openapi.json" },
  pages: "./docs/pages",
  serverUrl: api.url,
  zudoku: {
    metadata: {
      title: "{{titleCase name}} API",
      description: "HTTP API for {{titleCase name}}",
    },
  },
});
{{/if}}

// =============================================================================
// Outputs
// =============================================================================

export const app = env.register({
  description: "{{titleCase name}}",
});

// Exported so the bindings above are used, and because a stack's URLs are the
// first thing anyone wants after a deploy. `pulumi stack output` prints them.
{{#if service}}
export const apiUrl = api.url;
{{/if}}
{{#if temporal}}
export const workerTaskQueue = worker.taskQueue;
{{/if}}
