"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
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());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
exports.__esModule = true;
exports.makeServiceResolver = void 0;
var apollo_server_koa_1 = require("apollo-server-koa");
var const_1 = require("../const");
var database_1 = require("../database");
var utils_1 = require("../utils");
var apiType = "GRAPHQL";
exports.makeServiceResolver = function (resourcesMap) {
    return function (resource, hardDelete, supportsReturn) {
        return function (operation) {
            return function (obj, args, ctx, info) { return __awaiter(void 0, void 0, void 0, function () {
                var reqId, defaultInput, input, payload, context, options, keys, subquery, _a, props, fields, callDatabase, query, subPayload, _serviceResponse, serviceResponse, sql, _records, _b, data, singleRecord, debug, response, _c, seperator, notWhere, statementContext, distinct, fields_1, _searchCountResult, searchCountResult, sqlSearchCount, count, err_1;
                return __generator(this, function (_d) {
                    switch (_d.label) {
                        case 0:
                            reqId = ctx.reqId || "reqId no issued";
                            defaultInput = {
                                payload: {},
                                context: {},
                                options: {},
                                subquery: {}
                            };
                            input = __assign(__assign({}, defaultInput), args);
                            payload = input.payload, context = input.context, options = input.options, keys = input.keys, subquery = input.subquery;
                            _a = utils_1.extractSelectedFields(info), props = _a.props, fields = _a.fields;
                            callDatabase = props.includes("data");
                            if (!supportsReturn && ["create", "update"].includes(operation)) {
                                fields = [];
                            }
                            context.fields = fields;
                            if (context.orderBy) {
                                context.orderBy = utils_1.contextTransformer("orderBy", context.orderBy);
                            }
                            query = {
                                payload: operation === "update"
                                    ? __assign(__assign({}, payload), keys) : operation === "search"
                                    ? utils_1.gqlParsePayload(payload)
                                    : payload,
                                context: context,
                                requestId: reqId,
                                apiType: apiType,
                                hardDelete: hardDelete
                            };
                            subPayload = __assign(__assign({}, subquery), { requestId: reqId, apiType: apiType });
                            _serviceResponse = resource.hasSubquery
                                ? utils_1.callComplexResource(resourcesMap, resource.name, operation, query, subPayload)
                                : resource[operation](query);
                            return [4 /*yield*/, _serviceResponse];
                        case 1:
                            serviceResponse = _d.sent();
                            if (!serviceResponse.result) return [3 /*break*/, 11];
                            _d.label = 2;
                        case 2:
                            _d.trys.push([2, 9, , 10]);
                            sql = serviceResponse.result.sql.toString();
                            if (!callDatabase) return [3 /*break*/, 4];
                            return [4 /*yield*/, serviceResponse.result.sql];
                        case 3:
                            _b = _d.sent();
                            return [3 /*break*/, 5];
                        case 4:
                            _b = [];
                            _d.label = 5;
                        case 5:
                            _records = _b;
                            data = !supportsReturn && ["create", "update"].includes(operation)
                                ? operation === "update"
                                    ? [const_1.NON_RETURNING_SUCCESS_RESPONSE]
                                    : const_1.NON_RETURNING_SUCCESS_RESPONSE
                                : resource.transformRecords(_records);
                            singleRecord = ["read", "update"].includes(operation);
                            delete serviceResponse.result.sql;
                            debug = {
                                now: Date.now(),
                                reqId: reqId,
                                input: {
                                    payload: payload,
                                    context: context,
                                    options: options
                                },
                                serviceResponse: serviceResponse
                            };
                            if (subquery) {
                                // @ts-ignore
                                debug.input.subPayload = subPayload;
                            }
                            response = {
                                data: singleRecord ? (data.length ? data[0] : null) : data,
                                sql: sql,
                                debug: debug
                            };
                            if (!(callDatabase && operation === "search" && options.count)) return [3 /*break*/, 8];
                            _c = query.context, seperator = _c.seperator, notWhere = _c.notWhere, statementContext = _c.statementContext, distinct = _c.distinct, fields_1 = _c.fields;
                            query.context = { seperator: seperator, notWhere: notWhere, statementContext: statementContext, distinct: distinct, fields: fields_1 };
                            _searchCountResult = resource.hasSubquery
                                ? utils_1.callComplexResource(resourcesMap, resource.name, operation, query, subPayload)
                                : resource[operation](query);
                            return [4 /*yield*/, _searchCountResult];
                        case 6:
                            searchCountResult = (_d.sent()).result;
                            sqlSearchCount = database_1.genCountQuery(resource.db, searchCountResult.sql);
                            return [4 /*yield*/, sqlSearchCount];
                        case 7:
                            count = (_d.sent())[0].count;
                            response.count = count;
                            _d.label = 8;
                        case 8: return [2 /*return*/, response];
                        case 9:
                            err_1 = _d.sent();
                            // log error && // not a user input error
                            throw new apollo_server_koa_1.UserInputError("cnst.INTERNAL_SERVER_ERROR", {
                                detail: serviceResponse,
                                reqId: reqId
                            });
                        case 10: return [3 /*break*/, 12];
                        case 11: throw new apollo_server_koa_1.UserInputError("HTTP_STATUS.BAD_REQUEST", {
                            detail: serviceResponse,
                            reqId: reqId
                        });
                        case 12: return [2 /*return*/];
                    }
                });
            }); };
        };
    };
};
//# sourceMappingURL=resolvers.js.map