/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import type { LogAttributes, LogRecord } from '@opentelemetry/api-logs';
import { logs } from '@opentelemetry/api-logs';
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
import type { Config } from '../config/config.js';
import { safeJsonStringify } from '../utils/safeJsonStringify.js';
import { UserAccountManager } from '../utils/userAccountManager.js';
import {
  EVENT_API_ERROR,
  EVENT_API_CANCEL,
  EVENT_API_REQUEST,
  EVENT_API_RESPONSE,
  EVENT_CLI_CONFIG,
  EVENT_EXTENSION_UNINSTALL,
  EVENT_EXTENSION_ENABLE,
  EVENT_IDE_CONNECTION,
  EVENT_TOOL_CALL,
  EVENT_USER_PROMPT,
  EVENT_FLASH_FALLBACK,
  EVENT_NEXT_SPEAKER_CHECK,
  SERVICE_NAME,
  EVENT_SLASH_COMMAND,
  EVENT_CONVERSATION_FINISHED,
  EVENT_CHAT_COMPRESSION,
  EVENT_CONTENT_RETRY,
  EVENT_CONTENT_RETRY_FAILURE,
  EVENT_FILE_OPERATION,
  EVENT_RIPGREP_FALLBACK,
  EVENT_EXTENSION_INSTALL,
  EVENT_MODEL_SLASH_COMMAND,
  EVENT_EXTENSION_DISABLE,
  EVENT_SUBAGENT_EXECUTION,
  EVENT_MALFORMED_JSON_RESPONSE,
  EVENT_INVALID_CHUNK,
  EVENT_AUTH,
} from './constants.js';
import {
  recordApiErrorMetrics,
  recordApiResponseMetrics,
  recordChatCompressionMetrics,
  recordContentRetry,
  recordContentRetryFailure,
  recordFileOperationMetric,
  recordInvalidChunk,
  recordModelSlashCommand,
  recordSubagentExecutionMetrics,
  recordTokenUsageMetrics,
  recordToolCallMetrics,
} from './metrics.js';
import { QwenLogger } from './qwen-logger/qwen-logger.js';
import { isTelemetrySdkInitialized } from './sdk.js';
import type {
  ApiErrorEvent,
  ApiCancelEvent,
  ApiRequestEvent,
  ApiResponseEvent,
  FileOperationEvent,
  IdeConnectionEvent,
  StartSessionEvent,
  ToolCallEvent,
  UserPromptEvent,
  FlashFallbackEvent,
  NextSpeakerCheckEvent,
  LoopDetectedEvent,
  LoopDetectionDisabledEvent,
  SlashCommandEvent,
  ConversationFinishedEvent,
  KittySequenceOverflowEvent,
  ChatCompressionEvent,
  ContentRetryEvent,
  ContentRetryFailureEvent,
  RipgrepFallbackEvent,
  ToolOutputTruncatedEvent,
  ExtensionDisableEvent,
  ExtensionEnableEvent,
  ExtensionUninstallEvent,
  ExtensionInstallEvent,
  ModelSlashCommandEvent,
  SubagentExecutionEvent,
  MalformedJsonResponseEvent,
  InvalidChunkEvent,
  AuthEvent,
} from './types.js';
import type { UiEvent } from './uiTelemetry.js';
import { uiTelemetryService } from './uiTelemetry.js';

const shouldLogUserPrompts = (config: Config): boolean =>
  config.getTelemetryLogPromptsEnabled();

function getCommonAttributes(config: Config): LogAttributes {
  const userAccountManager = new UserAccountManager();
  const email = userAccountManager.getCachedGoogleAccount();
  return {
    'session.id': config.getSessionId(),
    ...(email && { 'user.email': email }),
  };
}

export function logCliConfiguration(
  config: Config,
  event: StartSessionEvent,
): void {
  QwenLogger.getInstance(config)?.logStartSessionEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    'event.name': EVENT_CLI_CONFIG,
    'event.timestamp': new Date().toISOString(),
    model: event.model,
    embedding_model: event.embedding_model,
    sandbox_enabled: event.sandbox_enabled,
    core_tools_enabled: event.core_tools_enabled,
    approval_mode: event.approval_mode,
    api_key_enabled: event.api_key_enabled,
    vertex_ai_enabled: event.vertex_ai_enabled,
    log_user_prompts_enabled: event.telemetry_log_user_prompts_enabled,
    file_filtering_respect_git_ignore: event.file_filtering_respect_git_ignore,
    debug_mode: event.debug_enabled,
    mcp_servers: event.mcp_servers,
    mcp_servers_count: event.mcp_servers_count,
    mcp_tools: event.mcp_tools,
    mcp_tools_count: event.mcp_tools_count,
    output_format: event.output_format,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: 'CLI configuration loaded.',
    attributes,
  };
  logger.emit(logRecord);
}

export function logUserPrompt(config: Config, event: UserPromptEvent): void {
  QwenLogger.getInstance(config)?.logNewPromptEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    'event.name': EVENT_USER_PROMPT,
    'event.timestamp': new Date().toISOString(),
    prompt_length: event.prompt_length,
    prompt_id: event.prompt_id,
  };

  if (event.auth_type) {
    attributes['auth_type'] = event.auth_type;
  }

  if (shouldLogUserPrompts(config)) {
    attributes['prompt'] = event.prompt;
  }

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `User prompt. Length: ${event.prompt_length}.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logToolCall(config: Config, event: ToolCallEvent): void {
  const uiEvent = {
    ...event,
    'event.name': EVENT_TOOL_CALL,
    'event.timestamp': new Date().toISOString(),
  } as UiEvent;
  uiTelemetryService.addEvent(uiEvent);
  QwenLogger.getInstance(config)?.logToolCallEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_TOOL_CALL,
    'event.timestamp': new Date().toISOString(),
    function_args: safeJsonStringify(event.function_args, 2),
  };
  if (event.error) {
    attributes['error.message'] = event.error;
    if (event.error_type) {
      attributes['error.type'] = event.error_type;
    }
  }

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Tool call: ${event.function_name}${event.decision ? `. Decision: ${event.decision}` : ''}. Success: ${event.success}. Duration: ${event.duration_ms}ms.`,
    attributes,
  };
  logger.emit(logRecord);
  recordToolCallMetrics(config, event.duration_ms, {
    function_name: event.function_name,
    success: event.success,
    decision: event.decision,
    tool_type: event.tool_type,
  });
}

export function logToolOutputTruncated(
  config: Config,
  event: ToolOutputTruncatedEvent,
): void {
  QwenLogger.getInstance(config)?.logToolOutputTruncatedEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': 'tool_output_truncated',
    'event.timestamp': new Date().toISOString(),
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Tool output truncated for ${event.tool_name}.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logFileOperation(
  config: Config,
  event: FileOperationEvent,
): void {
  QwenLogger.getInstance(config)?.logFileOperationEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    'event.name': EVENT_FILE_OPERATION,
    'event.timestamp': new Date().toISOString(),
    tool_name: event.tool_name,
    operation: event.operation,
  };

  if (event.lines) {
    attributes['lines'] = event.lines;
  }
  if (event.mimetype) {
    attributes['mimetype'] = event.mimetype;
  }
  if (event.extension) {
    attributes['extension'] = event.extension;
  }
  if (event.programming_language) {
    attributes['programming_language'] = event.programming_language;
  }

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `File operation: ${event.operation}. Lines: ${event.lines}.`,
    attributes,
  };
  logger.emit(logRecord);

  recordFileOperationMetric(config, {
    operation: event.operation,
    lines: event.lines,
    mimetype: event.mimetype,
    extension: event.extension,
    programming_language: event.programming_language,
  });
}

export function logApiRequest(config: Config, event: ApiRequestEvent): void {
  // QwenLogger.getInstance(config)?.logApiRequestEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_API_REQUEST,
    'event.timestamp': new Date().toISOString(),
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `API request to ${event.model}.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logFlashFallback(
  config: Config,
  event: FlashFallbackEvent,
): void {
  QwenLogger.getInstance(config)?.logFlashFallbackEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_FLASH_FALLBACK,
    'event.timestamp': new Date().toISOString(),
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Switching to flash as Fallback.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logRipgrepFallback(
  config: Config,
  event: RipgrepFallbackEvent,
): void {
  QwenLogger.getInstance(config)?.logRipgrepFallbackEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_RIPGREP_FALLBACK,
    'event.timestamp': new Date().toISOString(),
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Switching to grep as fallback.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logApiError(config: Config, event: ApiErrorEvent): void {
  const uiEvent = {
    ...event,
    'event.name': EVENT_API_ERROR,
    'event.timestamp': new Date().toISOString(),
  } as UiEvent;
  uiTelemetryService.addEvent(uiEvent);
  QwenLogger.getInstance(config)?.logApiErrorEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_API_ERROR,
    'event.timestamp': new Date().toISOString(),
    ['error.message']: event.error,
    model_name: event.model,
    duration: event.duration_ms,
  };

  if (event.error_type) {
    attributes['error.type'] = event.error_type;
  }
  if (typeof event.status_code === 'number') {
    attributes[SemanticAttributes.HTTP_STATUS_CODE] = event.status_code;
  }

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `API error for ${event.model}. Error: ${event.error}. Duration: ${event.duration_ms}ms.`,
    attributes,
  };
  logger.emit(logRecord);
  recordApiErrorMetrics(config, event.duration_ms, {
    model: event.model,
    status_code: event.status_code,
    error_type: event.error_type,
  });
}

export function logApiCancel(config: Config, event: ApiCancelEvent): void {
  const uiEvent = {
    ...event,
    'event.name': EVENT_API_CANCEL,
    'event.timestamp': new Date().toISOString(),
  } as UiEvent;
  uiTelemetryService.addEvent(uiEvent);
  QwenLogger.getInstance(config)?.logApiCancelEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_API_CANCEL,
    'event.timestamp': new Date().toISOString(),
    model_name: event.model,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `API request cancelled for ${event.model}.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logApiResponse(config: Config, event: ApiResponseEvent): void {
  const uiEvent = {
    ...event,
    'event.name': EVENT_API_RESPONSE,
    'event.timestamp': new Date().toISOString(),
  } as UiEvent;
  uiTelemetryService.addEvent(uiEvent);
  QwenLogger.getInstance(config)?.logApiResponseEvent(event);
  if (!isTelemetrySdkInitialized()) return;
  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_API_RESPONSE,
    'event.timestamp': new Date().toISOString(),
  };
  if (event.response_text) {
    attributes['response_text'] = event.response_text;
  }
  if (event.status_code) {
    if (typeof event.status_code === 'number') {
      attributes[SemanticAttributes.HTTP_STATUS_CODE] = event.status_code;
    }
  }

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `API response from ${event.model}. Status: ${event.status_code || 'N/A'}. Duration: ${event.duration_ms}ms.`,
    attributes,
  };
  logger.emit(logRecord);
  recordApiResponseMetrics(config, event.duration_ms, {
    model: event.model,
    status_code: event.status_code,
  });
  recordTokenUsageMetrics(config, event.input_token_count, {
    model: event.model,
    type: 'input',
  });
  recordTokenUsageMetrics(config, event.output_token_count, {
    model: event.model,
    type: 'output',
  });
  recordTokenUsageMetrics(config, event.cached_content_token_count, {
    model: event.model,
    type: 'cache',
  });
  recordTokenUsageMetrics(config, event.thoughts_token_count, {
    model: event.model,
    type: 'thought',
  });
  recordTokenUsageMetrics(config, event.tool_token_count, {
    model: event.model,
    type: 'tool',
  });
}

export function logLoopDetected(
  config: Config,
  event: LoopDetectedEvent,
): void {
  QwenLogger.getInstance(config)?.logLoopDetectedEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Loop detected. Type: ${event.loop_type}.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logLoopDetectionDisabled(
  config: Config,
  _event: LoopDetectionDisabledEvent,
): void {
  QwenLogger.getInstance(config)?.logLoopDetectionDisabledEvent();
}

export function logNextSpeakerCheck(
  config: Config,
  event: NextSpeakerCheckEvent,
): void {
  QwenLogger.getInstance(config)?.logNextSpeakerCheck(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_NEXT_SPEAKER_CHECK,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Next speaker check.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logSlashCommand(
  config: Config,
  event: SlashCommandEvent,
): void {
  QwenLogger.getInstance(config)?.logSlashCommandEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_SLASH_COMMAND,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Slash command: ${event.command}.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logIdeConnection(
  config: Config,
  event: IdeConnectionEvent,
): void {
  QwenLogger.getInstance(config)?.logIdeConnectionEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_IDE_CONNECTION,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Ide connection. Type: ${event.connection_type}.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logConversationFinishedEvent(
  config: Config,
  event: ConversationFinishedEvent,
): void {
  QwenLogger.getInstance(config)?.logConversationFinishedEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_CONVERSATION_FINISHED,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Conversation finished.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logChatCompression(
  config: Config,
  event: ChatCompressionEvent,
): void {
  QwenLogger.getInstance(config)?.logChatCompressionEvent(event);

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_CHAT_COMPRESSION,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Chat compression (Saved ${event.tokens_before - event.tokens_after} tokens)`,
    attributes,
  };
  logger.emit(logRecord);

  recordChatCompressionMetrics(config, {
    tokens_before: event.tokens_before,
    tokens_after: event.tokens_after,
  });
}

export function logKittySequenceOverflow(
  config: Config,
  event: KittySequenceOverflowEvent,
): void {
  QwenLogger.getInstance(config)?.logKittySequenceOverflowEvent(event);
  if (!isTelemetrySdkInitialized()) return;
  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
  };
  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Kitty sequence buffer overflow: ${event.sequence_length} bytes`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logMalformedJsonResponse(
  config: Config,
  event: MalformedJsonResponseEvent,
): void {
  QwenLogger.getInstance(config)?.logMalformedJsonResponseEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_MALFORMED_JSON_RESPONSE,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Malformed JSON response from ${event.model}.`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logInvalidChunk(
  config: Config,
  event: InvalidChunkEvent,
): void {
  QwenLogger.getInstance(config)?.logInvalidChunkEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    'event.name': EVENT_INVALID_CHUNK,
    'event.timestamp': event['event.timestamp'],
  };

  if (event.error_message) {
    attributes['error.message'] = event.error_message;
  }

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Invalid chunk received from stream.`,
    attributes,
  };
  logger.emit(logRecord);
  recordInvalidChunk(config);
}

export function logContentRetry(
  config: Config,
  event: ContentRetryEvent,
): void {
  QwenLogger.getInstance(config)?.logContentRetryEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_CONTENT_RETRY,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Content retry attempt ${event.attempt_number} due to ${event.error_type}.`,
    attributes,
  };
  logger.emit(logRecord);
  recordContentRetry(config);
}

export function logContentRetryFailure(
  config: Config,
  event: ContentRetryFailureEvent,
): void {
  QwenLogger.getInstance(config)?.logContentRetryFailureEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_CONTENT_RETRY_FAILURE,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `All content retries failed after ${event.total_attempts} attempts.`,
    attributes,
  };
  logger.emit(logRecord);
  recordContentRetryFailure(config);
}

export function logSubagentExecution(
  config: Config,
  event: SubagentExecutionEvent,
): void {
  QwenLogger.getInstance(config)?.logSubagentExecutionEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_SUBAGENT_EXECUTION,
    'event.timestamp': new Date().toISOString(),
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Subagent execution: ${event.subagent_name}.`,
    attributes,
  };
  logger.emit(logRecord);
  recordSubagentExecutionMetrics(
    config,
    event.subagent_name,
    event.status,
    event.terminate_reason,
  );
}

export function logModelSlashCommand(
  config: Config,
  event: ModelSlashCommandEvent,
): void {
  QwenLogger.getInstance(config)?.logModelSlashCommandEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_MODEL_SLASH_COMMAND,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Model slash command. Model: ${event.model_name}`,
    attributes,
  };
  logger.emit(logRecord);
  recordModelSlashCommand(config, event);
}

export function logExtensionInstallEvent(
  config: Config,
  event: ExtensionInstallEvent,
): void {
  QwenLogger.getInstance(config)?.logExtensionInstallEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_EXTENSION_INSTALL,
    'event.timestamp': new Date().toISOString(),
    extension_name: event.extension_name,
    extension_version: event.extension_version,
    extension_source: event.extension_source,
    status: event.status,
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Installed extension ${event.extension_name}`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logExtensionUninstall(
  config: Config,
  event: ExtensionUninstallEvent,
): void {
  QwenLogger.getInstance(config)?.logExtensionUninstallEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_EXTENSION_UNINSTALL,
    'event.timestamp': new Date().toISOString(),
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Uninstalled extension ${event.extension_name}`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logExtensionEnable(
  config: Config,
  event: ExtensionEnableEvent,
): void {
  QwenLogger.getInstance(config)?.logExtensionEnableEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_EXTENSION_ENABLE,
    'event.timestamp': new Date().toISOString(),
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Enabled extension ${event.extension_name}`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logExtensionDisable(
  config: Config,
  event: ExtensionDisableEvent,
): void {
  QwenLogger.getInstance(config)?.logExtensionDisableEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_EXTENSION_DISABLE,
    'event.timestamp': new Date().toISOString(),
  };

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Disabled extension ${event.extension_name}`,
    attributes,
  };
  logger.emit(logRecord);
}

export function logAuth(config: Config, event: AuthEvent): void {
  QwenLogger.getInstance(config)?.logAuthEvent(event);
  if (!isTelemetrySdkInitialized()) return;

  const attributes: LogAttributes = {
    ...getCommonAttributes(config),
    ...event,
    'event.name': EVENT_AUTH,
    'event.timestamp': new Date().toISOString(),
    auth_type: event.auth_type,
    action_type: event.action_type,
    status: event.status,
  };

  if (event.error_message) {
    attributes['error.message'] = event.error_message;
  }

  const logger = logs.getLogger(SERVICE_NAME);
  const logRecord: LogRecord = {
    body: `Auth event: ${event.action_type} ${event.status} for ${event.auth_type}`,
    attributes,
  };
  logger.emit(logRecord);
}
