// Copyright (C) 2026 Garudex Labs.  All Rights Reserved.
// Caracal, a product of Garudex Labs
//
// `caracal resource …` admin subcommands.

import type { CliConfig } from '../config.ts'
import { printSuccess } from '../style.ts'
import {
  buildAdminClient,
  fail,
  flagBool,
  flagList,
  flagString,
  parseArgs,
  printJSON,
  printTable,
  requireZone,
  showHelp,
  unknownVerb,
  usage,
} from './shared.ts'

export async function resourceCommand(argv: string[], cfg?: CliConfig): Promise<void> {
  const [verb, ...rest] = argv
  const ctx = buildAdminClient(cfg)
  const { client } = ctx
  const { positional, flags } = parseArgs(rest)
  const json = flagBool(flags, 'json')

  try {
    switch (verb) {
      case 'list': {
        const zoneId = requireZone(ctx, flags)
        const rows = await client.resources.list(zoneId)
        if (json) return printJSON(rows)
        return printTable(rows, ['id', 'identifier', 'name', 'upstream_url', 'gateway_application_id', 'scopes', 'credential_provider_id'])
      }
      case 'get': {
        const zoneId = requireZone(ctx, flags)
        const id = positional[0]
        if (!id) return usage('resource get <id> [--zone …]')
        return printJSON(await client.resources.get(zoneId, id))
      }
      case 'create': {
        const zoneId = requireZone(ctx, flags)
        const identifier = flagString(flags, 'identifier')
        const scopes = flagList(flags, 'scopes')
        if (!identifier || !scopes || scopes.length === 0) {
          return usage('resource create --identifier <id> --scopes a,b [--name …] [--upstream-url … --gateway-application-id …] [--prefix] [--provider …]')
        }
        return printJSON(await client.resources.create(zoneId, {
          identifier,
          scopes,
          name: flagString(flags, 'name'),
          upstream_url: flagString(flags, 'upstream-url'),
          gateway_application_id: flagString(flags, 'gateway-application-id'),
          prefix: flagBool(flags, 'prefix') || undefined,
          credential_provider_id: flagString(flags, 'provider'),
        }))
      }
      case 'patch': {
        const zoneId = requireZone(ctx, flags)
        const id = positional[0]
        if (!id) return usage('resource patch <id> [--identifier …] [--scopes …] [--upstream-url …] [--gateway-application-id …] [--name …] [--provider …] [--prefix=true|false]')
        return printJSON(await client.resources.patch(zoneId, id, {
          identifier: flagString(flags, 'identifier'),
          name: flagString(flags, 'name'),
          upstream_url: flagString(flags, 'upstream-url'),
          gateway_application_id: flagString(flags, 'gateway-application-id'),
          prefix: flags['prefix'] === undefined ? undefined : flagBool(flags, 'prefix'),
          scopes: flagList(flags, 'scopes'),
          credential_provider_id: flagString(flags, 'provider'),
        }))
      }
      case 'delete': {
        const zoneId = requireZone(ctx, flags)
        const id = positional[0]
        if (!id) return usage('resource delete <id> [--zone …]')
        await client.resources.delete(zoneId, id)
        printSuccess(`deleted ${id}`)
        return
      }
      case 'help':
      case '--help':
      case '-h':
        return help()
      default:
        return unknownVerb('resource', verb, help)
    }
  } catch (err) {
    fail(err)
  }
}

function help(): never {
  return showHelp(
    [
      'Usage: caracal resource <verb> [options]',
      '',
      'Verbs:',
      '  list                      List resources in a zone',
      '  get <id>                  Fetch a resource by ID as JSON',
      '  create                    Register a protected resource',
      '    --identifier <id>         Resource identifier URI (required)',
      '    --scopes a,b              Comma-separated list of scopes (required)',
      '    --name <n>                Human-readable name',
      '    --upstream-url <url>      Backend URL the gateway proxies to',
      '    --gateway-application-id <id> Gateway application for upstream routing',
      '    --prefix                  Match identifier as a prefix',
      '    --provider <id>           Credential provider ID',
      '  patch <id>                Update a resource',
      '    --identifier, --name, --upstream-url, --gateway-application-id, --scopes, --prefix=true|false, --provider',
      '  delete <id>               Permanently delete a resource',
      '',
      'Flags:',
      '  --zone <id>               Zone selector (or CARACAL_ZONE_ID)',
      '  --json                    Emit raw JSON',
      '  --help, -h                Show this help',
      '',
    ],
  )
}
