import { type array, type listable, type show } from "@ark/util";
import type { nodeOfKind, NodeSchema, Prerequisite, RootSchema } from "../kinds.ts";
import type { PredicateNode } from "../predicate.ts";
import type { NodeCompiler } from "../shared/compile.ts";
import type { BaseErrorContext, BaseNormalizedSchema, declareNode } from "../shared/declare.ts";
import type { ArkError } from "../shared/errors.ts";
import { type ConstraintKind, type nodeImplementationOf, type OpenNodeKind, type PrestructuralKind, type RefinementKind, type StructuralKind } from "../shared/implement.ts";
import type { JsonSchema } from "../shared/jsonSchema.ts";
import type { ToJsonSchema } from "../shared/toJsonSchema.ts";
import type { TraverseAllows, TraverseApply } from "../shared/traversal.ts";
import { type makeRootAndArrayPropertiesMutable } from "../shared/utils.ts";
import type { Structure, UndeclaredKeyBehavior } from "../structure/structure.ts";
import type { Domain } from "./domain.ts";
import type { Morph } from "./morph.ts";
import type { Proto } from "./proto.ts";
import { BaseRoot } from "./root.ts";
export declare namespace Intersection {
    type BasisKind = "domain" | "proto";
    type ChildKind = BasisKind | RefinementKind;
    type FlattenedChildKind = ChildKind | StructuralKind;
    type RefinementsInner = {
        [k in RefinementKind]?: intersectionChildInnerValueOf<k>;
    };
    interface Inner extends RefinementsInner {
        domain?: Domain.Node;
        proto?: Proto.Node;
        structure?: Structure.Node;
        predicate?: array<PredicateNode>;
    }
    namespace Inner {
        type mutable = makeRootAndArrayPropertiesMutable<Inner>;
    }
    type ConstraintsSchema<inferredBasis = any> = show<BaseNormalizedSchema & {
        domain?: Domain.Schema;
        proto?: Proto.Schema;
    } & conditionalRootOf<inferredBasis>>;
    type NormalizedSchema = Omit<ConstraintsSchema, StructuralKind | "undeclared">;
    type Schema<inferredBasis = any> = ConstraintsSchema<inferredBasis>;
    interface AstSchema extends BaseNormalizedSchema {
        intersection: readonly RootSchema[];
    }
    interface ErrorContext extends BaseErrorContext<"intersection">, Inner {
        errors: readonly ArkError[];
    }
    type Declaration = declareNode<{
        kind: "intersection";
        schema: Schema;
        normalizedSchema: NormalizedSchema;
        inner: Inner;
        reducibleTo: "intersection" | BasisKind;
        errorContext: ErrorContext;
        childKind: ChildKind;
    }>;
    type Node = IntersectionNode;
}
export declare class IntersectionNode extends BaseRoot<Intersection.Declaration> {
    basis: nodeOfKind<Intersection.BasisKind> | null;
    prestructurals: array<nodeOfKind<PrestructuralKind>>;
    refinements: array<nodeOfKind<RefinementKind>>;
    structure: Structure.Node | undefined;
    expression: string;
    get shallowMorphs(): array<Morph>;
    get defaultShortDescription(): string;
    protected innerToJsonSchema(ctx: ToJsonSchema.Context): JsonSchema;
    traverseAllows: TraverseAllows;
    traverseApply: TraverseApply;
    compile(js: NodeCompiler): void;
}
export declare const Intersection: {
    implementation: nodeImplementationOf<{
        intersectionIsOpen: false;
        prerequisite: unknown;
        kind: "intersection";
        schema: Intersection.Schema;
        normalizedSchema: Intersection.NormalizedSchema;
        inner: Intersection.Inner;
        reducibleTo: "intersection" | Intersection.BasisKind;
        errorContext: Intersection.ErrorContext;
        childKind: Intersection.ChildKind;
    }>;
    Node: typeof IntersectionNode;
};
export type ConditionalTerminalIntersectionRoot = {
    undeclared?: UndeclaredKeyBehavior;
};
type ConditionalTerminalIntersectionKey = keyof ConditionalTerminalIntersectionRoot;
type ConditionalIntersectionKey = ConstraintKind | ConditionalTerminalIntersectionKey;
export type constraintKindOf<t> = {
    [k in ConstraintKind]: t extends Prerequisite<k> ? k : never;
}[ConstraintKind];
type conditionalIntersectionKeyOf<t> = constraintKindOf<t> | (t extends object ? "undeclared" : never);
type intersectionChildSchemaValueOf<k extends Intersection.FlattenedChildKind> = k extends OpenNodeKind ? listable<NodeSchema<k>> : NodeSchema<k>;
type conditionalSchemaValueOfKey<k extends ConditionalIntersectionKey> = k extends Intersection.FlattenedChildKind ? intersectionChildSchemaValueOf<k> : ConditionalTerminalIntersectionRoot[k & ConditionalTerminalIntersectionKey];
type intersectionChildInnerValueOf<k extends Intersection.FlattenedChildKind> = k extends OpenNodeKind ? readonly nodeOfKind<k>[] : nodeOfKind<k>;
export type conditionalRootOf<t> = {
    [k in conditionalIntersectionKeyOf<t>]?: conditionalSchemaValueOfKey<k>;
};
export {};
