// Unified component constructors for TiDB cluster components.
// This file consolidates the individual component files (pd.libsonnet, tikv.libsonnet, etc.)
// into a single location with a unified template structure.
//
// Each component constructor now operates on a { spec: ..., metadata: ... } structure,
// allowing configurations to modify both the component spec and its metadata (e.g., labels).

local confs = import './configures.libsonnet';

{
  // Component metadata defaults
  local componentDefaults = {
    pd: {
      apiVersion: 'core.pingcap.com/v1alpha1',
      kind: 'PDGroup',
      image: 'hub.pingcap.net/tikv/pd/image:master',
      version: 'v9.0.0-alpha',
    },
    tikv: {
      apiVersion: 'core.pingcap.com/v1alpha1',
      kind: 'TiKVGroup',
      image: 'hub.pingcap.net/tikv/tikv/image:master',
      version: 'v9.0.0-alpha',
      preStop: {
        image: 'docker.io/pingcap/tidb-operator-prestop-checker:v2.1.0-alpha.10',
      },
    },
    tidb: {
      apiVersion: 'core.pingcap.com/v1alpha1',
      kind: 'TiDBGroup',
      image: 'hub.pingcap.net/pingcap/tidb/images/tidb-server:master',
      version: 'v9.0.0-alpha',
    },
    ticdc: {
      apiVersion: 'core.pingcap.com/v1alpha1',
      kind: 'TiCDCGroup',
      image: 'hub.pingcap.net/pingcap/ticdc/image:master',
      version: 'v9.0.0-alpha',
      preStop: {
        image: 'pingcap/tidb-operator-prestop-checker:v2.1.0-alpha.10'
      },
    },
    tiproxy: {
      apiVersion: 'core.pingcap.com/v1alpha1',
      kind: 'TiProxyGroup',
      image: 'hub.pingcap.net/pingcap/tiproxy/image:main',
      version: 'v9.0.0-alpha',
    },
    tiflash: {
      apiVersion: 'core.pingcap.com/v1alpha1',
      kind: 'TiFlashGroup',
      image: 'hub.pingcap.net/tikv/tiflash/image:master',
      version: 'v9.0.0-alpha',
    },
    tso: {
      apiVersion: 'core.pingcap.com/v1alpha1',
      kind: 'TSOGroup',
      image: 'hub.pingcap.net/tikv/pd/image:master',
      version: 'v9.0.0-alpha',
    },
    scheduling: {
      apiVersion: 'core.pingcap.com/v1alpha1',
      kind: 'SchedulingGroup',
      image: 'hub.pingcap.net/tikv/pd/image:master',
      version: 'v9.0.0-alpha',
    },
  },

  // Unified component constructor
  // name: component group name
  // componentType: one of 'pd', 'tikv', 'tidb', 'ticdc', 'tiproxy'
  // configurations: array of actions that will be applied to { spec: ..., metadata: ... }
  local makeComponent(name, componentType, configurations) =
    local defaults = componentDefaults[componentType];

    // Base structure with both spec and metadata
    local base = {
      spec: {
        cluster: { name: name },
        replicas: 1,
        template: {
          spec: {
            image: defaults.image,
            version: defaults.version,
            [if 'preStop' in defaults then 'preStop']: defaults.preStop,
            volumes: [],
          },
        },
      },
      metadata: {
        name: name,
      },
    };

    // Apply configurations and freeze config
    local configured = confs.apply(base, configurations + [confs.freezeConfig]);

    // Build final resource
    {
      apiVersion: defaults.apiVersion,
      kind: defaults.kind,
      metadata: configured.metadata,
      spec: configured.spec,
    },

  // Component constructors
  pd(name='basic', configurations=[]):: makeComponent(name, 'pd', configurations),
  tikv(name='basic', configurations=[]):: makeComponent(name, 'tikv', configurations),
  tidb(name='basic', configurations=[]):: makeComponent(name, 'tidb', configurations),
  ticdc(name='basic', configurations=[]):: makeComponent(name, 'ticdc', configurations),
  tiproxy(name='basic', configurations=[]):: makeComponent(name, 'tiproxy', configurations),
  tso(name='tso', configurations=[]):: makeComponent(name, 'tso', configurations),
  scheduling(name='schedule', configurations=[]):: makeComponent(name, 'scheduling', configurations),
  tiflash(name='tiflash', configurations=[]):: makeComponent(name, 'tiflash', configurations),
}
