"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FusionType = void 0;
const commandBase_js_1 = require("../validation/commandBase.js");
const ask_js_1 = __importDefault(require("./ask.js"));
const bm25_js_1 = __importDefault(require("./bm25.js"));
const generate_js_1 = require("./generate.js");
const group_js_1 = __importDefault(require("./group.js"));
const groupBy_js_1 = __importDefault(require("./groupBy.js"));
const hybrid_js_1 = __importDefault(require("./hybrid.js"));
const nearImage_js_1 = __importDefault(require("./nearImage.js"));
const nearMedia_js_1 = __importStar(require("./nearMedia.js"));
const nearObject_js_1 = __importDefault(require("./nearObject.js"));
const nearText_js_1 = __importDefault(require("./nearText.js"));
const nearVector_js_1 = __importDefault(require("./nearVector.js"));
const sort_js_1 = __importDefault(require("./sort.js"));
const where_js_1 = __importDefault(require("./where.js"));
var hybrid_js_2 = require("./hybrid.js");
Object.defineProperty(exports, "FusionType", { enumerable: true, get: function () { return hybrid_js_2.FusionType; } });
class GraphQLGetter extends commandBase_js_1.CommandBase {
    after;
    askString;
    bm25String;
    className;
    fields;
    groupString;
    hybridString;
    includesNearMediaFilter;
    limit;
    nearImageNotSet;
    nearMediaString;
    nearMediaType;
    nearObjectString;
    nearTextString;
    nearVectorString;
    offset;
    sortString;
    whereString;
    generateString;
    consistencyLevel;
    groupByString;
    tenant;
    autocut;
    constructor(client) {
        super(client);
        this.includesNearMediaFilter = false;
    }
    withFields = (fields) => {
        this.fields = fields;
        return this;
    };
    withClassName = (className) => {
        this.className = className;
        return this;
    };
    withAfter = (id) => {
        this.after = id;
        return this;
    };
    withGroup = (args) => {
        try {
            this.groupString = new group_js_1.default(args).toString();
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withWhere = (whereObj) => {
        try {
            this.whereString = new where_js_1.default(whereObj).toString();
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withNearText = (args) => {
        if (this.includesNearMediaFilter) {
            throw new Error('cannot use multiple near<Media> filters in a single query');
        }
        this.nearTextString = new nearText_js_1.default(args).toString();
        this.includesNearMediaFilter = true;
        return this;
    };
    withBm25 = (args) => {
        try {
            this.bm25String = new bm25_js_1.default(args).toString();
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withHybrid = (args) => {
        try {
            this.hybridString = new hybrid_js_1.default(args).toString();
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withNearObject = (args) => {
        if (this.includesNearMediaFilter) {
            throw new Error('cannot use multiple near<Media> filters in a single query');
        }
        try {
            this.nearObjectString = new nearObject_js_1.default(args).toString();
            this.includesNearMediaFilter = true;
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withAsk = (askObj) => {
        try {
            this.askString = new ask_js_1.default(askObj).toString();
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withNearMedia = (args) => {
        if (this.includesNearMediaFilter) {
            throw new Error('cannot use multiple near<Media> filters in a single query');
        }
        try {
            this.nearMediaString = new nearMedia_js_1.default(args).toString();
            this.nearMediaType = args.type;
            this.includesNearMediaFilter = true;
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withNearImage = (args) => {
        if (this.includesNearMediaFilter) {
            throw new Error('cannot use multiple near<Media> filters in a single query');
        }
        try {
            this.nearMediaString = new nearImage_js_1.default(args).toString();
            this.nearMediaType = nearMedia_js_1.NearMediaType.Image;
            this.includesNearMediaFilter = true;
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withNearAudio = (args) => {
        return this.withNearMedia({
            ...args,
            type: nearMedia_js_1.NearMediaType.Audio,
            media: args.audio,
        });
    };
    withNearVideo = (args) => {
        return this.withNearMedia({
            ...args,
            type: nearMedia_js_1.NearMediaType.Video,
            media: args.video,
        });
    };
    withNearThermal = (args) => {
        return this.withNearMedia({
            ...args,
            type: nearMedia_js_1.NearMediaType.Thermal,
            media: args.thermal,
        });
    };
    withNearDepth = (args) => {
        return this.withNearMedia({
            ...args,
            type: nearMedia_js_1.NearMediaType.Depth,
            media: args.depth,
        });
    };
    withNearIMU = (args) => {
        return this.withNearMedia({
            ...args,
            type: nearMedia_js_1.NearMediaType.IMU,
            media: args.imu,
        });
    };
    withNearVector = (args) => {
        if (this.includesNearMediaFilter) {
            throw new Error('cannot use multiple near<Media> filters in a single query');
        }
        try {
            this.nearVectorString = new nearVector_js_1.default(args).toString();
            this.includesNearMediaFilter = true;
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withLimit = (limit) => {
        this.limit = limit;
        return this;
    };
    withOffset = (offset) => {
        this.offset = offset;
        return this;
    };
    withAutocut = (autocut) => {
        this.autocut = autocut;
        return this;
    };
    withSort = (args) => {
        this.sortString = new sort_js_1.default(args).toString();
        return this;
    };
    withGenerate = (args) => {
        this.generateString = new generate_js_1.GraphQLGenerate(args).toString();
        return this;
    };
    withConsistencyLevel = (level) => {
        this.consistencyLevel = level;
        return this;
    };
    withGroupBy = (args) => {
        try {
            this.groupByString = new groupBy_js_1.default(args).toString();
        }
        catch (e) {
            this.addError(e.toString());
        }
        return this;
    };
    withTenant = (tenant) => {
        this.tenant = tenant;
        return this;
    };
    validateIsSet = (prop, name, setter) => {
        if (prop == undefined || prop == null || prop.length == 0) {
            this.addError(`${name} must be set - set with ${setter}`);
        }
    };
    validate = () => {
        this.validateIsSet(this.className, 'className', '.withClassName(className)');
        this.validateIsSet(this.fields, 'fields', '.withFields(fields)');
    };
    do = () => {
        let params = '';
        this.validate();
        if (this.errors.length > 0) {
            return Promise.reject(new Error('invalid usage: ' + this.errors.join(', ')));
        }
        let args = [];
        if (this.whereString) {
            args = [...args, `where:${this.whereString}`];
        }
        if (this.nearTextString) {
            args = [...args, `nearText:${this.nearTextString}`];
        }
        if (this.nearObjectString) {
            args = [...args, `nearObject:${this.nearObjectString}`];
        }
        if (this.askString) {
            args = [...args, `ask:${this.askString}`];
        }
        if (this.nearMediaString) {
            args = [...args, `near${this.nearMediaType}:${this.nearMediaString}`];
        }
        if (this.nearVectorString) {
            args = [...args, `nearVector:${this.nearVectorString}`];
        }
        if (this.bm25String) {
            args = [...args, `bm25:${this.bm25String}`];
        }
        if (this.hybridString) {
            args = [...args, `hybrid:${this.hybridString}`];
        }
        if (this.groupString) {
            args = [...args, `group:${this.groupString}`];
        }
        if (this.limit) {
            args = [...args, `limit:${this.limit}`];
        }
        if (this.offset) {
            args = [...args, `offset:${this.offset}`];
        }
        if (this.autocut) {
            args = [...args, `autocut:${this.autocut}`];
        }
        if (this.sortString) {
            args = [...args, `sort:[${this.sortString}]`];
        }
        if (this.after) {
            args = [...args, `after:"${this.after}"`];
        }
        if (this.generateString) {
            if (this.fields?.includes('_additional')) {
                this.fields.replace('_additional{', `_additional{${this.generateString}`);
            }
            else {
                this.fields = this.fields?.concat(` _additional{${this.generateString}}`);
            }
        }
        if (this.consistencyLevel) {
            args = [...args, `consistencyLevel:${this.consistencyLevel}`];
        }
        if (this.groupByString) {
            args = [...args, `groupBy:${this.groupByString}`];
        }
        if (this.tenant) {
            args = [...args, `tenant:"${this.tenant}"`];
        }
        if (args.length > 0) {
            params = `(${args.join(',')})`;
        }
        return this.client.query(`{Get{${this.className}${params}{${this.fields}}}}`);
    };
}
exports.default = GraphQLGetter;
