/***** Main Sparnatural Query Structure *****/
export type SparnaturalQuery = {
    type: "query";
    subType: "SELECT";
    variables: (TermVariable | PatternBind)[];
    solutionModifiers: SolutionModifiers;
    distinct?: true;
    where: PatternBgpSameSubject;
    metadata?: {
        id?: string;
        lang?: string;
        label?: {
            [key: string]: string;
        };
        description?: {
            [key: string]: string;
        };
        [key: string]: any;
    };
};
export type PatternBase = {
    type: "pattern";
    subType: string;
};
export type PatternBind = PatternBase & {
    subType: "bind";
    expression: ExpressionAggregate;
    variable: TermVariable;
};
/***** End Main Sparnatural Query Structure *****/
/***** BGP-same-subject extension of Sparnatural *****/
export type PatternBgpSameSubject = PatternBase & {
    subType: "bgpSameSubject";
    subject: TermTypedVariable;
    predicateObjectPairs: PredicateObjectPair[];
};
export type PredicateObjectPair = {
    type: "predicateObjectPair";
    subType?: "optional" | "notExists";
    predicate: TermIri;
    object: ObjectCriteria;
};
export type ObjectCriteria = {
    type: "objectCriteria";
    variable: TermTypedVariable;
    values?: ValuePatternRow[];
    filters?: LabelledFilter[];
    predicateObjectPairs?: PredicateObjectPair[];
};
export type LabelledFilter = {
    type: "labelledFilter";
    label: string;
    filter: DateFilter | MapFilter | NumberFilter | SearchFilter;
};
export interface DateFilter {
    type: "dateFilter";
    start?: string | undefined;
    stop?: string | undefined;
}
export interface MapFilter {
    type: "mapFilter";
    coordType: "Polygon" | "Rectangle";
    coordinates: LatLng[][];
}
export interface LatLng {
    lat: number;
    lng: number;
    alt?: number | undefined;
}
export interface NumberFilter {
    type: "numberFilter";
    min?: number | undefined;
    max?: number | undefined;
}
export interface SearchFilter {
    type: "searchFilter";
    search: string;
}
/***** End BGP-same-subject extension of Sparnatural *****/
/***** Context definition, for defining prefixes and base URIs *****/
/***** End Context definition *****/
/***** Solution modifiers (order and limit/offset) *****/
export type SolutionModifierBase = AstNode & {
    type: "solutionModifier";
    subType: string;
};
export type Ordering = {
    descending: boolean;
    expression: TermVariable;
};
export type SolutionModifierOrder = SolutionModifierBase & {
    subType: "order";
    orderDefs: Ordering[];
};
export type SolutionModifierLimitOffset = SolutionModifierBase & {
    subType: "limitOffset";
    limit: number;
};
export type SolutionModifier = SolutionModifierOrder | SolutionModifierLimitOffset;
export type SolutionModifiers = {
    order?: SolutionModifierOrder;
    limitOffset?: SolutionModifierLimitOffset;
};
/***** End Solution modifiers *****/
/***** Values clause *****/
/**
 * A single list of assignments maps the variable identifier to the value
 *
 VALUES (?x ?y) { (<http://example.com/Museum1> "foo") }

"values": [
{
  "x": {
    "type": "term",
    "subType": "namedNode",
    "value": "http://example.com/Museum1"
  },
  "y": {
    "type": "term",
    "subType": "literal",
    "value": "foo"
  }
}
]
 */
export type ValuePatternRow = Record<string, TermIri | TermLiteral | TermLabelledIri | undefined>;
export type PatternValues = PatternBase & {
    subType: "values";
    variables: TermVariable[];
    values: ValuePatternRow[];
};
/***** End Values clause *****/
/***** Generic Expression structure (function calls, operations, or aggregates) *****/
export type ExpressionBase = AstNode & {
    type: "expression";
    subType: string;
};
type ExpressionAggregateBase = ExpressionBase & {
    subType: "aggregate";
    distinct: boolean;
    expression: [TermVariable];
};
export type ExpressionAggregateDefault = ExpressionAggregateBase & {
    expression: [TermVariable];
    aggregation: string;
};
export type ExpressionAggregateSeparator = ExpressionAggregateBase & {
    expression: [TermVariable];
    aggregation: string;
    separator: string;
};
export type ExpressionAggregate = ExpressionAggregateDefault | ExpressionAggregateSeparator;
/***** End Generic Expression structure *****/
/***** Base RDF terms : literals with lang/datatypes, and IRIs, and variables *****/
export type TermBase = {
    type: "term";
    subType: string;
};
export type TermLiteralBase = TermBase & {
    subType: "literal";
    value: string;
};
export type TermLiteralStr = TermLiteralBase & {
    langOrIri: undefined;
};
export type TermLiteralLangStr = TermLiteralBase & {
    langOrIri: string;
};
export type TermLiteralTyped = TermLiteralBase & {
    langOrIri: TermIri;
};
export type TermLiteral = TermLiteralStr | TermLiteralLangStr | TermLiteralTyped;
export type TermVariable = TermBase & {
    subType: "variable";
    value: string;
};
export type TermIriBase = TermBase & {
    subType: "namedNode";
};
export type TermIriFull = TermIriBase & {
    value: string;
};
export type TermIri = TermIriFull;
/** When we will implement prefixes, we will add this:

export type TermIriPrefixed = TermIriBase & {
  value: string;
  prefix: string;
};

export type TermIri = TermIriFull;
**/
export type TermLabelledIri = TermIriFull & {
    label: string;
};
export type TermTypedVariable = TermVariable & {
    rdfType: string;
};
export type GraphTerm = TermIri | TermLiteral | TermLabelledIri;
export type Term = GraphTerm | TermVariable | TermTypedVariable;
/***** End RDF terms *****/
export type AstNode = {
    type: string;
    subType: string;
};
export {};
