var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import Debug from 'debug';
import { generateApolloClient } from '@deep-foundation/hasura/client.js';
import { HasuraApi } from '@deep-foundation/hasura/api.js';
import { DeepClient } from './client.js';
const debug = Debug('deeplinks:bool_exp');
const log = debug.extend('log');
const error = debug.extend('error');
export const api = new HasuraApi({
    path: process.env.DEEPLINKS_HASURA_PATH,
    ssl: !!+process.env.DEEPLINKS_HASURA_SSL,
    secret: process.env.DEEPLINKS_HASURA_SECRET,
});
const client = generateApolloClient({
    path: `${process.env.DEEPLINKS_HASURA_PATH}/v1/graphql`,
    ssl: !!+process.env.DEEPLINKS_HASURA_SSL,
    secret: process.env.DEEPLINKS_HASURA_SECRET,
});
const deep = new DeepClient({
    apolloClient: client,
});
export const itemReplaceSymbol = 777777777777;
export const userReplaceSymbol = 777777777778;
export const itemPublicSymbol = 'X-Deep-Item-Id';
export const userPublicSymbol = 'X-Deep-User-Id';
export const applyBoolExpToLink = (sql, linkId) => {
    return sql.replace(`${itemReplaceSymbol}`, `${linkId}`);
};
export const boolExpToSQL = (boolExpId, boolExpValue) => __awaiter(void 0, void 0, void 0, function* () {
    var _a, _b, _c;
    log('boolExpToSQL', boolExpId, boolExpValue);
    let gql, explained, sql;
    try {
        if (typeof (boolExpValue) !== 'object') {
            throw new Error('boolExpValue must be object');
        }
        const serializedQuery = deep.serializeQuery(boolExpValue);
        gql = JSON.stringify(serializedQuery === null || serializedQuery === void 0 ? void 0 : serializedQuery.where).replace(/"([^"]+)":/g, '$1:');
        gql = gql.replace(new RegExp(`'${userPublicSymbol}'`, 'g'), userReplaceSymbol);
        gql = gql.replace(new RegExp(`"${userPublicSymbol}"`, 'g'), userReplaceSymbol);
        gql = gql.replace(new RegExp(`'${itemPublicSymbol}'`, 'g'), itemReplaceSymbol);
        gql = gql.replace(new RegExp(`"${itemPublicSymbol}"`, 'g'), itemReplaceSymbol);
        explained = yield api.explain(`{ links(where: { _and: [{ id: { _eq: ${itemReplaceSymbol} } }, ${gql}] }, limit: 1) { id } }`);
        sql = (_b = (_a = explained === null || explained === void 0 ? void 0 : explained.data) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.sql;
        if (sql) {
            const convertedSql = `SELECT json_array_length("root") as "root" FROM (${sql}) as "root"`;
            const boolExp = yield deep.select({ link_id: { _eq: boolExpId } }, { table: 'bool_exp', returning: 'id link_id' });
            const boolExpLink = (_c = boolExp === null || boolExp === void 0 ? void 0 : boolExp.data) === null || _c === void 0 ? void 0 : _c[0];
            log('boolExpLink', boolExpLink);
            if (boolExpLink) {
                const mutateResult = yield deep.update(boolExpLink.id, {
                    value: convertedSql,
                }, { table: 'bool_exp' });
            }
            else {
                const mutateResult = yield deep.insert({
                    link_id: boolExpId,
                    value: convertedSql,
                }, { table: 'bool_exp' });
            }
        }
    }
    catch (e) {
        error(e);
        error('error', gql, explained, sql);
    }
});
//# sourceMappingURL=bool_exp_to_sql.js.map