"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    IngestionPipeline: function() {
        return IngestionPipeline;
    },
    addNodesToVectorStores: function() {
        return addNodesToVectorStores;
    },
    runTransformations: function() {
        return runTransformations;
    }
});
const _Node = require("../Node.js");
const _config = require("../cloud/config.js");
const _types = require("../cloud/types.js");
const _utils = require("../cloud/utils.js");
const _IngestionCache = require("./IngestionCache.js");
const _index = require("./strategies/index.js");
async function runTransformations(nodesToRun, transformations, transformOptions = {}, { inPlace = true, cache, docStoreStrategy } = {}) {
    let nodes = nodesToRun;
    if (!inPlace) {
        nodes = [
            ...nodesToRun
        ];
    }
    if (docStoreStrategy) {
        nodes = await docStoreStrategy.transform(nodes);
    }
    for (const transform of transformations){
        if (cache) {
            const hash = (0, _IngestionCache.getTransformationHash)(nodes, transform);
            const cachedNodes = await cache.get(hash);
            if (cachedNodes) {
                nodes = cachedNodes;
            } else {
                nodes = await transform.transform(nodes, transformOptions);
                await cache.put(hash, nodes);
            }
        } else {
            nodes = await transform.transform(nodes, transformOptions);
        }
    }
    return nodes;
}
class IngestionPipeline {
    transformations = [];
    documents;
    reader;
    vectorStore;
    vectorStores;
    docStore;
    docStoreStrategy = _index.DocStoreStrategy.UPSERTS;
    cache;
    disableCache = false;
    client;
    clientParams;
    projectName = _types.DEFAULT_PROJECT_NAME;
    name = _types.DEFAULT_PIPELINE_NAME;
    _docStoreStrategy;
    constructor(init){
        Object.assign(this, init);
        this.clientParams = {
            apiKey: init?.apiKey,
            baseUrl: init?.baseUrl
        };
        if (!this.docStore) {
            this.docStoreStrategy = _index.DocStoreStrategy.NONE;
        }
        this.vectorStores = this.vectorStores ?? {
            [_Node.ModalityType.TEXT]: this.vectorStore
        };
        this._docStoreStrategy = (0, _index.createDocStoreStrategy)(this.docStoreStrategy, this.docStore, Object.values(this.vectorStores));
        if (!this.disableCache) {
            this.cache = new _IngestionCache.IngestionCache();
        }
    }
    async prepareInput(documents, nodes) {
        const inputNodes = [];
        if (documents) {
            inputNodes.push(documents);
        }
        if (nodes) {
            inputNodes.push(nodes);
        }
        if (this.documents) {
            inputNodes.push(this.documents);
        }
        if (this.reader) {
            inputNodes.push(await this.reader.loadData());
        }
        return inputNodes.flat();
    }
    async run(args = {}, transformOptions) {
        args.cache = args.cache ?? this.cache;
        args.docStoreStrategy = args.docStoreStrategy ?? this._docStoreStrategy;
        const inputNodes = await this.prepareInput(args.documents, args.nodes);
        const nodes = await runTransformations(inputNodes, this.transformations, transformOptions, args);
        if (this.vectorStores) {
            const nodesToAdd = nodes.filter((node)=>node.embedding);
            await addNodesToVectorStores(nodesToAdd, this.vectorStores);
        }
        return nodes;
    }
    async getClient() {
        if (!this.client) {
            this.client = await (0, _utils.getClient)(this.clientParams);
        }
        return this.client;
    }
    async register(params) {
        const client = await this.getClient();
        const inputNodes = await this.prepareInput(params.documents, params.nodes);
        const project = await client.project.upsertProject({
            name: this.projectName
        });
        if (!project.id) {
            throw new Error("Project ID should be defined");
        }
        // upload
        const pipeline = await client.project.upsertPipelineForProject(project.id, await (0, _config.getPipelineCreate)({
            pipelineName: this.name,
            pipelineType: "PLAYGROUND",
            transformations: this.transformations,
            inputNodes
        }));
        if (!pipeline.id) {
            throw new Error("Pipeline ID must be defined");
        }
        // Print playground URL if not running remote
        if (params.verbose) {
            console.log(`Pipeline available at: ${(0, _utils.getAppBaseUrl)(this.clientParams?.baseUrl)}/project/${project.id}/playground/${pipeline.id}`);
        }
        return pipeline.id;
    }
}
async function addNodesToVectorStores(nodes, vectorStores, nodesAdded) {
    const nodeMap = (0, _Node.splitNodesByType)(nodes);
    for(const type in nodeMap){
        const nodes = nodeMap[type];
        if (nodes) {
            const vectorStore = vectorStores[type];
            if (!vectorStore) {
                throw new Error(`Cannot insert nodes of type ${type} without assigned vector store`);
            }
            const newIds = await vectorStore.add(nodes);
            if (nodesAdded) {
                await nodesAdded(newIds, nodes, vectorStore);
            }
        }
    }
}
