/// <reference path="./app.globals.d.ts" />
import { Bindings, HttpContext, IApplication, IContainer, IController, IMiddleware, IPathName, IServiceProvider, PathLoader, UseKey } from "@h3ravel/shared";
import { H3, H3Event } from "h3";
import { HttpContext as HttpContext$1 } from "@h3ravel/http";

//#region src/Contracts/ServiceProviderConstructor.d.ts
type ServiceProviderConstructor = (new (app: Application) => ServiceProvider) & IServiceProvider;
type AServiceProvider = (new (_app: Application) => ServiceProvider) & Partial<ServiceProvider>;
type OServiceProvider = (new (_app: Application) => Partial<ServiceProvider>) & Partial<ServiceProvider>;
//#endregion
//#region src/Container.d.ts
type IBinding = UseKey | (new (..._args: any[]) => unknown);
declare class Container implements IContainer {
  bindings: Map<IBinding, () => unknown>;
  singletons: Map<IBinding, unknown>;
  /**
   * Check if the target has any decorators
   *
   * @param target
   * @returns
   */
  static hasAnyDecorator<C extends abstract new (...args: any[]) => any>(target: C): boolean;
  static hasAnyDecorator<F extends (...args: any[]) => any>(target: F): boolean;
  /**
   * Bind a transient service to the container
   */
  bind<T>(key: new (...args: any[]) => T, factory: () => T): void;
  bind<T extends UseKey>(key: T, factory: () => Bindings[T]): void;
  /**
   * Remove one or more transient services from the container
   */
  unbind<T extends UseKey>(key: T | T[]): void;
  /**
   * Bind a singleton service to the container
   */
  singleton<T extends UseKey>(key: T | (new (..._args: any[]) => Bindings[T]), factory: (app: this) => Bindings[T]): void;
  /**
   * Resolve a service from the container
   */
  make<T extends UseKey>(key: T): Bindings[T];
  make<C extends abstract new (...args: any[]) => any>(key: C): InstanceType<C>;
  make<F extends (...args: any[]) => any>(key: F): ReturnType<F>;
  /**
   * Automatically build a class with constructor dependency injection
   */
  private build;
  /**
   * Check if a service is registered
   */
  has(key: UseKey): boolean;
}
//#endregion
//#region src/ServiceProvider.d.ts
declare const Inference: {
  new (): IServiceProvider;
};
declare abstract class ServiceProvider extends Inference {
  /**
   * The current app instance
   */
  protected app: Application;
  /**
   * Unique Identifier for the service providers
   */
  static uid?: number;
  /**
   * Sort order
   */
  static order?: `before:${string}` | `after:${string}` | string | undefined;
  /**
   * Sort priority
   */
  static priority: number;
  /**
   * Indicate that this service provider only runs in console
   */
  static console: boolean;
  /**
   * List of registered console commands
   */
  registeredCommands?: (new (app: any, kernel: any) => any)[];
  constructor(app: Application);
  /**
   * Register bindings to the container.
   * Runs before boot().
   */
  abstract register(...app: unknown[]): void | Promise<void>;
  /**
   * Perform post-registration booting of services.
   * Runs after all providers have been registered.
   */
  boot?(...app: unknown[]): void | Promise<void>;
  /**
   * Register the listed service providers.
   *
   * @param commands An array of console commands to register.
   *
   * @deprecated since version 1.16.0. Will be removed in future versions, use `registerCommands` instead
   */
  commands(commands: (new (app: any, kernel: any) => any)[]): void;
  /**
   * Register the listed service providers.
   *
   * @param commands An array of console commands to register.
   */
  registerCommands(commands: (new (app: any, kernel: any) => any)[]): void;
}
//#endregion
//#region src/Application.d.ts
declare class Application extends Container implements IApplication {
  paths: PathLoader;
  context?: (event: H3Event) => Promise<HttpContext>;
  private tries;
  private booted;
  private basePath;
  private versions;
  private static versions;
  private providers;
  protected externalProviders: Array<AServiceProvider>;
  protected filteredProviders: Array<string>;
  /**
   * List of registered console commands
   */
  registeredCommands: (new (app: any, kernel: any) => any)[];
  constructor(basePath: string);
  /**
   * Register core bindings into the container
   */
  protected registerBaseBindings(): void;
  protected loadOptions(): Promise<void>;
  /**
   * Get all registered providers
   */
  getRegisteredProviders(): ServiceProvider[];
  /**
   * Load default and optional providers dynamically
   *
   * Auto-Registration Behavior
   *
   * Minimal App: Loads only core, config, http, router by default.
   * Full-Stack App: Installs database, mail, queue, cache → they self-register via their providers.
   */
  protected getConfiguredProviders(): Promise<Array<AServiceProvider>>;
  protected getAllProviders(): Promise<Array<AServiceProvider>>;
  /**
   * Configure and Dynamically register all configured service providers, then boot the app.
   *
   * @param providers All regitererable service providers
   * @param filtered A list of service provider name strings we do not want to register at all cost
   * @param autoRegisterProviders If set to false, service providers will not be auto discovered and registered.
   *
   * @returns
   */
  quickStartup(providers: Array<AServiceProvider>, filtered?: string[], autoRegisterProviders?: boolean): Promise<this>;
  /**
   * Dynamically register all configured providers
   *
   * @param autoRegister If set to false, service providers will not be auto discovered and registered.
   */
  registerConfiguredProviders(autoRegister?: boolean): Promise<void>;
  /**
   * Register service providers
   *
   * @param providers
   * @param filtered
   */
  registerProviders(providers: Array<AServiceProvider>, filtered?: string[]): void;
  /**
   * Register a provider
   */
  register(provider: ServiceProvider): Promise<void>;
  /**
   * Register the listed service providers.
   *
   * @param commands An array of console commands to register.
   */
  withCommands(commands: (new (app: any, kernel: any) => any)[]): this;
  /**
   * checks if the application is running in CLI
   */
  runningInConsole(): boolean;
  getRuntimeEnv(): 'browser' | 'node' | 'unknown';
  /**
   * Boot all service providers after registration
   */
  boot(): Promise<this>;
  /**
   * Fire up the developement server using the user provided arguments
   *
   * Port will be auto assigned if provided one is not available
   *
   * @param h3App The current H3 app instance
   * @param preferedPort If provided, this will overide the port set in the evironment
   */
  fire(): Promise<this>;
  fire(h3App: H3, preferredPort?: number): Promise<this>;
  /**
   * Get the base path of the app
   *
   * @returns
   */
  getBasePath(): string;
  /**
   * Dynamically retrieves a path property from the class.
   * Any property ending with "Path" is accessible automatically.
   *
   * @param name - The base name of the path property
   * @returns
   */
  getPath(name: IPathName, suffix?: string): string;
  /**
   * Programatically set the paths.
   *
   * @param name - The base name of the path property
   * @param path - The new path
   * @returns
   */
  setPath(name: IPathName, path: string): void;
  /**
   * Returns the installed version of the system core and typescript.
   *
   * @returns
   */
  getVersion(key: string): string;
  /**
   * Returns the installed version of the system core and typescript.
   *
   * @returns
   */
  static getVersion(key: string): string;
}
//#endregion
//#region src/Contracts/H3ravelContract.d.ts
interface EntryConfig {
  /**
   * @param h3 You can provide your own `H3` app instance, this is usefull when `@h3ravel/http`
   * is not installed.
   */
  h3?: H3;
  /**
   * Determines if we should initialize the app on call.
   *
   * @default false
   */
  initialize?: boolean;
  /**
   * Determines if service providers should be auto discovered and registered or not.
   *
   * @default false
   */
  autoload?: boolean;
  /**
   * A list of service provider name strings we do not want to register at all cost
   *
   * @default []
   */
  filteredProviders?: string[];
}
//#endregion
//#region src/Controller.d.ts
/**
 * Base controller class
 */
declare abstract class Controller implements IController {
  protected app: Application;
  constructor(app: Application);
  show?(..._ctx: any[]): any;
  index?(..._ctx: any[]): any;
  store?(..._ctx: any[]): any;
  update?(..._ctx: any[]): any;
  destroy?(..._ctx: any[]): any;
}
//#endregion
//#region src/Di/ContainerResolver.d.ts
declare class ContainerResolver {
  private app;
  constructor(app: Application);
  resolveMethodParams<I extends Record<string, any>>(instance: I, method: keyof I, ..._default: any[]): Promise<I>;
  static isClass(C: any): boolean;
}
//#endregion
//#region src/Di/Inject.d.ts
declare function Inject(...dependencies: string[]): (target: any) => void;
/**
 * Allows binding dependencies to both class and class methods
 *
 * @returns
 */
declare function Injectable(): ClassDecorator & MethodDecorator;
//#endregion
//#region src/Exceptions/ConfigException.d.ts
declare class ConfigException extends Error {
  key: string;
  constructor(key: string, type?: 'any' | 'config' | 'env', cause?: unknown);
}
//#endregion
//#region src/H3ravel.d.ts
/**
 * Simple global entry point for H3ravel applications
 *
 * @param providers
 * @param basePath
 * @param callback
 */
declare const h3ravel: (
/**
 * List of intial service providers to register with your app
 */
providers?: Exclude<OServiceProvider, "app" | "commands">[],
/**
 * Entry path of your app
 */
basePath?: string,
/**
 * Configuration option to pass to the initializer
 */
config?: EntryConfig,
/**
 * final middleware function to call once the server is fired up
 */
middleware?: (ctx: HttpContext$1) => Promise<unknown>) => Promise<Application>;
//#endregion
//#region src/Http/Kernel.d.ts
/**
 * Kernel class handles middleware execution and response transformations.
 * It acts as the core middleware pipeline for HTTP requests.
 */
declare class Kernel {
  protected context: (event: H3Event) => HttpContext | Promise<HttpContext>;
  protected middleware: IMiddleware[];
  /**
   * @param context - A factory function that converts an H3Event into an HttpContext.
   * @param middleware - An array of middleware classes that will be executed in sequence.
   */
  constructor(context: (event: H3Event) => HttpContext | Promise<HttpContext>, middleware?: IMiddleware[]);
  /**
   * Handles an incoming request and passes it through middleware before invoking the next handler.
   *
   * @param event - The raw H3 event object.
   * @param next - A callback function that represents the next layer (usually the controller or final handler).
   * @returns A promise resolving to the result of the request pipeline.
   */
  handle(event: H3Event, next: (ctx: HttpContext) => Promise<unknown>): Promise<unknown>;
  /**
   * Sequentially runs middleware in the order they were registered.
   *
   * @param context - The standardized HttpContext.
   * @param next - Callback to execute when middleware completes.
   * @returns A promise resolving to the final handler's result.
   */
  private runMiddleware;
  /**
   * Utility function to determine if a value is a plain object or array.
   *
   * @param value - The value to check.
   * @returns True if the value is a plain object or array, otherwise false.
   */
  private isPlainObject;
}
//#endregion
//#region src/ProviderRegistry.d.ts
type ProviderCtor = (new (_app: Application) => ServiceProvider) & Partial<ServiceProvider>;
declare class ProviderRegistry {
  private static providers;
  private static priorityMap;
  private static filteredProviders;
  private static sortable;
  /**
   * Set wether providers should be sorted or not.
   *
   * @returns
   */
  static setSortable(sort?: boolean): void;
  /**
   * Get a unique identifier for the Provider.
   *
   * @param provider
   * @returns
   */
  private static getKey;
  /**
   * Register one or more providers.
   * Duplicate constructors will be ignored.
   *
   * @param providers
   * @returns
   */
  static register(...providers: ProviderCtor[]): void;
  /**
   * Bulk register providers from an array.
   *
   * @param providers
   * @returns
   */
  static registerMany(providers: ProviderCtor[]): void;
  /**
   * Set the filtered providers.
   *
   * @returns
   */
  static setFiltered(filtered: string[]): void;
  /**
   * Resolve (instantiate) all providers with the given application or Service Container.
   *
   * @param app
   * @returns
   */
  static resolve(app: Application, useServiceContainer?: boolean): Promise<ServiceProvider[]>;
  /**
   * Sort the service providers
   *
   * @param providers
   * @returns
   */
  static sort(providers: ProviderCtor[]): ProviderCtor[];
  /**
   * Sort service providers
   */
  static doSort(): void;
  /**
   * Log the service providers in a table
   *
   * @param priorityMap
   */
  static log<P extends ServiceProvider>(providers?: Array<P> | Map<string, P>): void;
  /**
   * Get all registered providers as an array.
   *
   * @returns
   */
  static all(): ProviderCtor[];
  /**
   * Check if a provider is already registered.
   *
   * @param provider
   * @returns
   */
  static has(provider: ProviderCtor): boolean;
  /**
   * Automatically search for and discover service providers in packages.
   *
   * @param autoRegister
   * @returns
   */
  static discoverProviders(autoRegister?: boolean): Promise<ProviderCtor[]>;
  /**
   * Get the content of the package.json file
   *
   * @param manifestPath
   * @returns
   */
  private static getManifest;
}
//#endregion
//#region src/Providers/CoreServiceProvider.d.ts
/**
 * Bootstraps core services and bindings.
 *
 * Bind essential services to the container (logger, config repository).
 * Register app-level singletons.
 * Set up exception handling.
 *
 * Auto-Registered
 */
declare class CoreServiceProvider extends ServiceProvider {
  static priority: number;
  register(): void;
  boot(): void | Promise<void>;
}
//#endregion
//#region src/Registerer.d.ts
declare class Registerer {
  private app;
  constructor(app: Application);
  static register(app: Application): void;
  bootRegister(): void;
  private appPath;
  private basePath;
  private publicPath;
  private storagePath;
  private databasePath;
}
//#endregion
export { AServiceProvider, Application, ConfigException, Container, ContainerResolver, Controller, CoreServiceProvider, EntryConfig, Inject, Injectable, Kernel, OServiceProvider, ProviderRegistry, Registerer, ServiceProvider, ServiceProviderConstructor, h3ravel };