// ABOUTME: Mock provider for testing that returns predictable responses
// ABOUTME: Avoids expensive LLM calls during test execution

import {
  ProviderMessage,
  ProviderResponse,
  ProviderConfig,
  type WireTool,
} from '@lace/agent/providers/base-provider';
import { BaseMockProvider } from './base-mock-provider';

interface TestProviderConfig extends ProviderConfig {
  mockResponse?: string;
  shouldError?: boolean;
  delay?: number;
}

export class TestProvider extends BaseMockProvider {
  private readonly mockResponse: string;
  private readonly shouldError: boolean;
  private readonly delay: number;

  constructor(config: TestProviderConfig = {}) {
    super(config);
    this.mockResponse = config.mockResponse || 'Mock response from test provider';
    this.shouldError = config.shouldError || false;
    this.delay = config.delay || 10; // 10ms default delay
  }

  get providerName(): string {
    return 'test-provider';
  }

  get supportsStreaming(): boolean {
    return false;
  }

  diagnose(): Promise<{ connected: boolean; models: string[]; error?: string }> {
    if (this.shouldError) {
      return Promise.resolve({
        connected: false,
        models: [],
        error: 'Mock provider error',
      });
    }

    return Promise.resolve({
      connected: true,
      models: ['test-model'],
    });
  }

  protected async _createResponseImpl(
    _messages: ProviderMessage[],
    _tools: WireTool[],
    _model: string,
    _signal?: AbortSignal
  ): Promise<ProviderResponse> {
    // Simulate network delay
    await new Promise((resolve) => setTimeout(resolve, this.delay));

    if (this.shouldError) {
      throw new Error('Mock provider error during response creation');
    }

    return {
      content: this.mockResponse,
      toolCalls: [],
      usage: {
        promptTokens: 10,
        completionTokens: 20,
        totalTokens: 30,
      },
      stopReason: 'end_turn',
    };
  }

  protected async _createStreamingResponseImpl(
    _messages: ProviderMessage[],
    _tools: WireTool[],
    _model: string,
    _signal?: AbortSignal
  ): Promise<ProviderResponse> {
    // For test provider, just return the same as non-streaming
    return await this._createResponseImpl(_messages, _tools, _model, _signal);
  }
}
