/*
 * Copyright 2026, Salesforce, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Type definitions for external dependencies
// Note: These modules are used at runtime but don't need TypeScript declarations here
// since they're external dependencies and the bundled code handles them

// Type definitions that should be available from o11y packages
interface Environment {
  appName: string;
  sdkVersion: string;
}

interface Instrumentation {
  log(schema: unknown, data: { message: string }): void;
}

interface InstrumentedAppMethods {
  registerLogCollector(collector: any, options: { retroactive: boolean }): void;
  registerMetricsCollector(collector: any): void;
  simpleCollector: any;
}

interface SimpleCollector {
  hasData: boolean;
  estimatedByteSize: number;
  getRawContentsOfCoreEnvelope(): unknown;
}

/** Re-exported from @salesforce/core so consumers can use one import. Requires @salesforce/core when using getConnection. */
import type { Connection } from "@salesforce/core";
export type { Connection };

/** Options for O11yService.initialize. */
export interface InitializeOptions {
  /** Relative path from instance root for dynamic o11y upload. A default is used if omitted. */
  dynamicO11yUploadEndpointPath?: string;
}

// Main O11yService class declaration
export declare class O11yService {
  O11Y_UPLOAD_THRESHOLD_BYTES: number;
  o11yUploadEndpoint: string | undefined;
  instrumentation: Instrumentation | undefined;
  a4dO11ySchema: unknown;
  readonly environment: Record<string, string>;

  private static instances: Map<string, O11yService>;
  private static sharedInstrumentation: Instrumentation | null;
  private static sharedInstrApp: InstrumentedAppMethods | null;
  private static sharedO11yModules: any | null;
  private static sharedProtoEncoderFunc:
    | ((input: unknown) => Uint8Array)
    | null;
  private extensionName: string;

  private constructor();

  static getInstance(extensionId: string): O11yService;
  initialize(
    extensionName: string,
    o11yUploadEndpoint: string,
    getConnection?: () => Promise<Connection>,
    options?: InitializeOptions,
  ): Promise<void>;
  private initializeSharedResources(): Promise<void>;
  logEvent(properties?: { [key: string]: any }): void;
  logEventWithSchema(properties: { [key: string]: any }, schema: unknown): void;
  upload(): Promise<void>;
  initSimpleCollector(
    o11yApp: InstrumentedAppMethods,
    environment: Environment,
    o11yModules: any | null,
  ): Promise<SimpleCollector>;
  uploadAsNeededAsync(
    ignoreThreshold?: boolean,
  ): Promise<PromiseSettledResult<Response>[]>;
  uploadToFalconAsync(binary: Uint8Array): Promise<Response>;
  postRequest(endpoint: string, body: any): Promise<any>;
  forceFlush(): Promise<void>;
  enableAutoBatching(options?: BatchingOptions): () => void;
  getBatchStatus(): BatchStatus;
}

export interface BatchingOptions {
  flushInterval?: number;
  thresholdBytes?: number;
  checkInterval?: number;
  enableShutdownHook?: boolean;
  enableBeforeExitHook?: boolean;
}

export interface BatchStatus {
  hasData: boolean;
  estimatedByteSize: number;
  thresholdBytes: number;
  isOverThreshold: boolean;
}
