import type {
  HttpClient,
  HttpClientConfig,
  RuntimeDb,
  RuntimeDalContext,
  RuntimeEnv,
  RuntimeHeaders,
  RuntimeOptions,
  RuntimeResponse,
} from "./runtime/index";

export interface TestkitSuite<TSetup = unknown> {
  options: RuntimeOptions;
  setup: () => TSetup | null;
  exec: (setupData: TSetup | null) => unknown;
}

export interface HeaderBuilderContext {
  env: RuntimeEnv;
}

export type HeaderBuilder<TSetup = unknown> = (
  setupData?: TSetup | null,
  context?: HeaderBuilderContext
) => RuntimeHeaders | void;

export interface AuthAdapter<TSetup = unknown> {
  setup?: (context: { env: RuntimeEnv }) => TSetup;
  headers?: HeaderBuilder<TSetup>;
}

export interface HttpSuiteContext<TSetup = unknown> {
  env: RuntimeEnv;
  req: HttpClient<TSetup>["request"];
  rawReq: HttpClient["raw"];
  getWithHeaders: HttpClient<TSetup>["getWithHeaders"];
  setupData: TSetup | null;
  session: TSetup | null;
}

export interface HttpSuiteConfig<TSetup = unknown> {
  auth?: AuthAdapter<TSetup> | null;
  env?: RuntimeEnv;
  headers?: HeaderBuilder<TSetup>;
  profile?: string;
  rawHeaders?: HeaderBuilder<never>;
  options?: RuntimeOptions;
}

export interface DalSuiteContext<TSetup = unknown> {
  db: RuntimeDb;
  dal: RuntimeDalContext;
  setupData: TSetup | null;
}

export interface DalSuiteConfig<TSetup = unknown> {
  db?: RuntimeDb;
  options?: RuntimeOptions;
  setup?: (context: { db: RuntimeDb; dal: RuntimeDalContext }) => TSetup;
}

export declare function defineHttpSuite<TSetup = unknown>(
  run: (context: HttpSuiteContext<TSetup>) => unknown
): TestkitSuite<TSetup>;

export declare function defineHttpSuite<TSetup = unknown>(
  config: HttpSuiteConfig<TSetup>,
  run: (context: HttpSuiteContext<TSetup>) => unknown
): TestkitSuite<TSetup>;

export declare function defineDalSuite<TSetup = unknown>(
  run: (context: DalSuiteContext<TSetup>) => unknown
): TestkitSuite<TSetup>;

export declare function defineDalSuite<TSetup = unknown>(
  config: DalSuiteConfig<TSetup>,
  run: (context: DalSuiteContext<TSetup>) => unknown
): TestkitSuite<TSetup>;

export declare function createAuthAdapter<TSetup = unknown>(
  adapter?: AuthAdapter<TSetup>
): AuthAdapter<TSetup>;

export type {
  HttpClient,
  HttpClientConfig,
  RuntimeDb,
  RuntimeDalContext,
  RuntimeEnv,
  RuntimeHeaders,
  RuntimeOptions,
  RuntimeResponse,
};
