import * as types from './types.js';

/**
 * Abstract Core Request class that defines the interface for all HTTP/HTTPS requests
 */
export abstract class CoreRequest<
  TOptions extends types.ICoreRequestOptions = types.ICoreRequestOptions,
  TResponse = any,
> {
  /**
   * Tests if a URL is a unix socket
   */
  static isUnixSocket(url: string): boolean {
    const unixRegex = /^(http:\/\/|https:\/\/|)unix:/;
    return unixRegex.test(url);
  }

  /**
   * Parses socket path and route from unix socket URL
   * Handles both full URLs (http://unix:/path/to/socket:/route) and pre-stripped paths (unix:/path/to/socket:/route)
   * Returns clean file system path for socketPath (e.g., /var/run/docker.sock)
   */
  static parseUnixSocketUrl(url: string): { socketPath: string; path: string } {
    // Strip http:// or https:// prefix if present
    // This makes the method work with both full URLs and pre-stripped paths
    let cleanUrl = url;
    if (cleanUrl.startsWith('http://')) {
      cleanUrl = cleanUrl.substring('http://'.length);
    } else if (cleanUrl.startsWith('https://')) {
      cleanUrl = cleanUrl.substring('https://'.length);
    }

    // Strip unix: prefix if present to get clean file system path
    if (cleanUrl.startsWith('unix:')) {
      cleanUrl = cleanUrl.substring('unix:'.length);
    }

    // Parse the socket path and HTTP path
    // Format: /path/to/socket:/route/path
    const parseRegex = /(.*):(.*)/;
    const result = parseRegex.exec(cleanUrl);
    return {
      socketPath: result[1],
      path: result[2],
    };
  }

  protected url: string;
  protected options: TOptions;

  constructor(url: string, options?: TOptions) {
    this.url = url;
    this.options = options || ({} as TOptions);
  }

  /**
   * Fire the request and return a response
   */
  abstract fire(): Promise<TResponse>;

  /**
   * Fire the request and return the raw response (platform-specific)
   */
  abstract fireCore(): Promise<any>;
}
