import * as astro from 'astro';
import { Tags } from 'exiftool-vendored';
import { Loader } from 'astro/loaders';
import { ZodTypeAny } from 'astro/zod';

type ExifToolTagKeys = keyof Tags;
type ExifPresets = "location" | "camera" | "exposure" | "datetime" | "technical" | "metadata" | "basic";
type ExifPresetTagMap = {
    basic: Extract<ExifToolTagKeys, "FileSize" | "ImageWidth" | "ImageHeight">;
    camera: Extract<ExifToolTagKeys, "Make" | "Model" | "LensModel" | "Lens" | "LensID" | "LensInfo" | "LensSerialNumber" | "SerialNumber" | "BodySerialNumber" | "CameraSerialNumber" | "LensMake" | "LensSpecification" | "MaxAperture" | "MinFocalLength" | "MaxFocalLength">;
    exposure: Extract<ExifToolTagKeys, "ISO" | "FNumber" | "ExposureTime" | "ShutterSpeed" | "FocalLength" | "FocalLengthIn35mmFormat" | "Flash" | "WhiteBalance" | "ExposureMode" | "MeteringMode">;
    datetime: Extract<ExifToolTagKeys, "DateTimeOriginal" | "CreateDate" | "DateTime">;
    location: Extract<ExifToolTagKeys, "GPSLatitude" | "GPSLongitude" | "GPSAltitude" | "Country" | "State" | "City" | "Location" | "Sub-location" | "GPSAreaInformation" | "Country-PrimaryLocationCode" | "Province-State">;
    technical: Extract<ExifToolTagKeys, "ColorSpace" | "Orientation" | "Software" | "SceneType" | "SceneCaptureType">;
    metadata: Extract<ExifToolTagKeys, "Artist" | "Copyright" | "ImageDescription" | "Keywords" | "Title" | "Subject">;
};
interface ExifDirectoryOptions {
    pattern: string | string[];
    base?: string;
}
interface ExifLoaderOptions {
    imagesDir?: ExifDirectoryOptions;
    extensions?: string[];
    presets?: ExifPresets[];
    tags?: ExifToolTagKeys[];
    excludeTags?: ExifToolTagKeys[];
    extractAll?: boolean;
    includeRawExif?: boolean;
}
interface ExifCollectionDefinition<S extends ZodTypeAny = ZodTypeAny> {
    loader: Loader;
    schema: S;
}
type PresetsToTagUnion<PSel extends readonly ExifPresets[] | undefined> = PSel extends readonly ExifPresets[] ? ExifPresetTagMap[PSel[number]] : never;
type CombinedSelectedTagElement<TSel extends readonly ExifToolTagKeys[] | undefined, PSel extends readonly ExifPresets[] | undefined> = (TSel extends readonly ExifToolTagKeys[] ? TSel[number] : never) | PresetsToTagUnion<PSel>;
type MaybeUndefinedSelected<TSel extends readonly ExifToolTagKeys[] | undefined, PSel extends readonly ExifPresets[] | undefined> = [TSel] extends [undefined] ? [PSel] extends [undefined] ? undefined : ReadonlyArray<CombinedSelectedTagElement<TSel, PSel>> : ReadonlyArray<CombinedSelectedTagElement<TSel, PSel>>;
interface ExifLocation {
    coordinates: {
        latitude: number;
        longitude: number;
        altitude: number | null;
    } | null;
    country: string | null;
    state: string | null;
    city: string | null;
    location: string | null;
    sublocation: string | null;
    gpsAreaInformation: string | null;
    countryCode: string | null;
    provinceState: string | null;
}
interface ExifMetadata {
    artist: string | null;
    copyright: string | null;
    description: string | null;
    keywords: string | string[] | null;
    rating: number | null;
    title: string | null;
    subject: string | string[] | null;
}
interface BaseExifData {
    fileName: string;
    mtime: string;
}
interface BasicExifData {
    fileSize: number;
    width: number | null;
    height: number | null;
}
interface CameraExifData {
    make: string | null;
    model: string | null;
    lens: string | null;
}
interface ExposureExifData {
    iso: number | string | null;
    aperture: number | string | null;
    shutterSpeed: number | string | null;
    focalLength: number | string | null;
    focalLength35mm: number | string | null;
    flash: number | string | null;
    whiteBalance: number | string | null;
    exposureMode: number | string | null;
    meteringMode: number | string | null;
}
interface DateTimeExifData {
    dateTime: string | null;
}
interface LocationExifData {
    location: ExifLocation;
}
interface TechnicalExifData {
    colorSpace: number | string | null;
    orientation: number | string | null;
    quality: number | string | null;
    software: string | null;
    sceneMode: number | string | null;
}
interface MetadataExifData {
    metadata: ExifMetadata;
}
interface RawExifData {
    rawExif: ExifMetadata;
}
interface CompleteExifData extends BaseExifData, BasicExifData, CameraExifData, ExposureExifData, DateTimeExifData, LocationExifData, TechnicalExifData, MetadataExifData {
}
type ExifData<T extends Record<string, boolean | undefined>> = BaseExifData & (T["basic"] extends false ? {} : BasicExifData) & (T["camera"] extends true ? CameraExifData : {}) & (T["exposure"] extends true ? ExposureExifData : {}) & (T["datetime"] extends true ? DateTimeExifData : {}) & (T["location"] extends true ? LocationExifData : {}) & (T["technical"] extends true ? TechnicalExifData : {}) & (T["metadata"] extends true ? MetadataExifData : {});
interface ImportedExifCollectionEntry<T = any> {
    id: string;
    collection: string;
    data: T;
    defaultImport: astro.ImageMetadata | null;
}
type SerializableValue<T> = T extends Date ? string : T extends {
    toDate(): any;
} ? string : T extends (infer U)[] ? SerializableValue<U>[] : T extends {
    num: number;
    den: number;
} ? number : T extends string | number | boolean ? T : string | number | boolean | null;
type AllSerializedExifTags = {
    [K in ExifToolTagKeys]?: SerializableValue<Tags[K]> | null | undefined;
};
interface BaseAlwaysFields {
    fileName: string;
    mtime: string;
    FileSize?: number;
}
type UniversalExifData = BaseAlwaysFields & AllSerializedExifTags;
type RawExifShape = {
    rawExif?: Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined>;
};
type NarrowedExifData<T extends readonly ExifToolTagKeys[] | undefined, E extends readonly ExifToolTagKeys[] | undefined = undefined> = BaseAlwaysFields & (T extends readonly any[] ? E extends readonly ExifToolTagKeys[] ? Omit<Pick<AllSerializedExifTags, T[number]>, E[number]> : Pick<AllSerializedExifTags, T[number]> : T extends undefined ? {} : E extends readonly ExifToolTagKeys[] ? Omit<AllSerializedExifTags, E[number]> : AllSerializedExifTags) & RawExifShape;
type ExtractAllExifData<E extends readonly ExifToolTagKeys[] | undefined = undefined> = BaseAlwaysFields & (E extends readonly ExifToolTagKeys[] ? Omit<AllSerializedExifTags, E[number]> : AllSerializedExifTags) & RawExifShape;
type ExtractAllExifDataNoRaw<E extends readonly ExifToolTagKeys[] | undefined = undefined> = BaseAlwaysFields & (E extends readonly ExifToolTagKeys[] ? Omit<AllSerializedExifTags, E[number]> : AllSerializedExifTags);
type NarrowedExifDataNoRaw<T extends readonly ExifToolTagKeys[] | undefined, E extends readonly ExifToolTagKeys[] | undefined = undefined> = BaseAlwaysFields & (T extends readonly any[] ? E extends readonly ExifToolTagKeys[] ? Omit<Pick<AllSerializedExifTags, T[number]>, E[number]> : Pick<AllSerializedExifTags, T[number]> : T extends undefined ? {} : E extends readonly ExifToolTagKeys[] ? Omit<AllSerializedExifTags, E[number]> : AllSerializedExifTags);
declare function exifTags<T extends readonly ExifToolTagKeys[]>(...tags: T): T;
type InferExifData<T> = T extends {
    schema: infer S;
} ? S extends {
    _type: infer U;
} ? U : S extends {
    shape: infer R;
} ? {
    [K in keyof R]: any;
} : unknown : unknown;

export { exifTags };
export type { AllSerializedExifTags, BaseAlwaysFields, BaseExifData, BasicExifData, CameraExifData, CombinedSelectedTagElement, CompleteExifData, DateTimeExifData, ExifCollectionDefinition, ExifData, ExifDirectoryOptions, ExifLoaderOptions, ExifLocation, ExifMetadata, ExifPresetTagMap, ExifPresets, ExifToolTagKeys, ExposureExifData, ExtractAllExifData, ExtractAllExifDataNoRaw, ImportedExifCollectionEntry, InferExifData, LocationExifData, MaybeUndefinedSelected, MetadataExifData, NarrowedExifData, NarrowedExifDataNoRaw, PresetsToTagUnion, RawExifData, RawExifShape, SerializableValue, TechnicalExifData, UniversalExifData };
