import { buildListingDecoder } from '@centreon/ui';
import { JsonDecoder } from 'ts.data.json';
import {
  AgentConfiguration,
  AgentType,
  CMAConfiguration,
  InstallationCommand,
  TelegrafConfiguration
} from '../models';

export const agentConfigurationsListingDecoder = buildListingDecoder({
  entityDecoder: JsonDecoder.object(
    {
      id: JsonDecoder.number,
      isAgentInitiated: JsonDecoder.optional(JsonDecoder.boolean),
      name: JsonDecoder.string,
      type: JsonDecoder.enumeration<AgentType>(AgentType, 'Agent type'),
      pollers: JsonDecoder.array(
        JsonDecoder.object(
          {
            id: JsonDecoder.number,
            name: JsonDecoder.string,
            isCentral: JsonDecoder.optional(JsonDecoder.boolean)
          },
          'poller',
          {
            isCentral: 'is_central'
          }
        ),
        'pollers'
      )
    },
    'Agent configuration',
    {
      isAgentInitiated: 'is_agent_initiated'
    }
  ),
  entityDecoderName: 'Listing agents configuration',
  listingDecoderName: 'Agents configuration'
});

const telegrafConfigurationDecoder = JsonDecoder.object<TelegrafConfiguration>(
  {
    otelPrivateKey: JsonDecoder.nullable(JsonDecoder.string),
    otelPublicCertificate: JsonDecoder.nullable(JsonDecoder.string),
    otelCaCertificate: JsonDecoder.nullable(JsonDecoder.string),
    confPrivateKey: JsonDecoder.nullable(JsonDecoder.string),
    confServerPort: JsonDecoder.number,
    confCertificate: JsonDecoder.nullable(JsonDecoder.string)
  },
  'Telegraf configuration',
  {
    otelPrivateKey: 'otel_private_key',
    otelCaCertificate: 'otel_ca_certificate',
    otelPublicCertificate: 'otel_public_certificate',
    confCertificate: 'conf_certificate',
    confPrivateKey: 'conf_private_key',
    confServerPort: 'conf_server_port'
  }
);

const cmaConfigurationDecoder = JsonDecoder.object<CMAConfiguration>(
  {
    port: JsonDecoder.optional(JsonDecoder.nullable(JsonDecoder.number)),
    tokens: JsonDecoder.optional(
      JsonDecoder.array(
        JsonDecoder.object(
          {
            creatorId: JsonDecoder.number,
            name: JsonDecoder.string
          },
          'token',
          { creatorId: 'creator_id' }
        ),
        'tokens'
      )
    ),
    agentInitiated: JsonDecoder.boolean,
    createHostAuto: JsonDecoder.optional(JsonDecoder.boolean),
    pollerInitiated: JsonDecoder.boolean,
    otelPublicCertificate: JsonDecoder.nullable(JsonDecoder.string),
    otelCaCertificate: JsonDecoder.nullable(JsonDecoder.string),
    otelPrivateKey: JsonDecoder.nullable(JsonDecoder.string),
    hosts: JsonDecoder.array(
      JsonDecoder.object(
        {
          address: JsonDecoder.string,
          port: JsonDecoder.number,
          pollerCaCertificate: JsonDecoder.nullable(JsonDecoder.string),
          pollerCaName: JsonDecoder.nullable(JsonDecoder.string),
          name: JsonDecoder.optional(JsonDecoder.string),
          id: JsonDecoder.optional(JsonDecoder.number),
          token: JsonDecoder.optional(
            JsonDecoder.object(
              {
                creatorId: JsonDecoder.number,
                name: JsonDecoder.string
              },
              'token',
              { creatorId: 'creator_id' }
            )
          )
        },
        'Host configuration',
        {
          pollerCaCertificate: 'poller_ca_certificate',
          pollerCaName: 'poller_ca_name'
        }
      ),
      'Host configurations'
    )
  },
  'CMA configuration',
  {
    agentInitiated: 'agent_initiated',
    createHostAuto: 'create_host_auto',
    pollerInitiated: 'poller_initiated',
    otelPrivateKey: 'otel_private_key',
    otelPublicCertificate: 'otel_public_certificate',
    otelCaCertificate: 'otel_ca_certificate'
  }
);

export const agentConfigurationDecoder = JsonDecoder.object<AgentConfiguration>(
  {
    name: JsonDecoder.string,
    connectionMode: JsonDecoder.string,
    type: JsonDecoder.enumeration<AgentType>(AgentType, 'Agent type'),
    pollers: JsonDecoder.array(
      JsonDecoder.object(
        {
          id: JsonDecoder.number,
          name: JsonDecoder.string
        },
        'poller'
      ),
      'pollers'
    ),
    configuration: JsonDecoder.oneOf<TelegrafConfiguration | CMAConfiguration>(
      [telegrafConfigurationDecoder, cmaConfigurationDecoder],
      'Agent configuration configuration'
    )
  },
  'Agent configuration',
  {
    connectionMode: 'connection_mode'
  }
);

export const installationCommandDecoder =
  JsonDecoder.object<InstallationCommand>(
    {
      linuxScriptCommand: JsonDecoder.string,
      windowsScriptCommand: JsonDecoder.string
    },
    'Agent configuration',
    {
      linuxScriptCommand: 'linux_installation_command',
      windowsScriptCommand: 'windows_installation_command'
    }
  );

export const tokenDecoder = JsonDecoder.object(
  {
    name: JsonDecoder.string,
    creator: JsonDecoder.object(
      {
        id: JsonDecoder.number,
        name: JsonDecoder.string
      },
      'Creator'
    )
  },
  'ListedToken'
).map(({ name, creator }) => {
  return {
    name,
    creatorId: creator.id,
    id: `${name}_${creator?.id}`,
    token_name: name
  };
});

export const listTokensDecoder = buildListingDecoder({
  entityDecoder: tokenDecoder,
  entityDecoderName: 'Tokens',
  listingDecoderName: 'listTokens'
});
