"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const types_1 = __importDefault(require("../types"));
const datalayer_libs_1 = require("./datalayer-libs");
const middleware_component_1 = __importDefault(require("../middleware/middleware-component"));
const graphql_1 = require("graphql");
exports.ENTRY_INSTANCE_TYPE = "EntryComponent";
;
exports.createEntryProps = (props) => {
    const entryProps = {
        createEntryFields: () => {
            const fields = Object.keys(props.data).reduce((result, key) => {
                result[key] = { type: props.data[key] };
                return result;
            }, {});
            fields[props.primaryKey] = { type: graphql_1.GraphQLString };
            fields[props.rangeKey] = { type: graphql_1.GraphQLString };
            return fields;
        },
        createEntryType: (prefix) => {
            return new graphql_1.GraphQLObjectType({
                name: prefix + props.id,
                fields: () => entryProps.createEntryFields()
            });
        },
        createKeyArgs: () => {
            const args = {};
            args[props.primaryKey] = { name: props.primaryKey, type: graphql_1.GraphQLString };
            args[props.rangeKey] = { name: props.rangeKey, type: graphql_1.GraphQLString };
            return args;
        },
        createEntryArgs: () => {
            const args = Object.keys(props.data).reduce((result, key) => {
                result[key] = { name: key, type: graphql_1.GraphQLString };
                return result;
            }, {});
            args[props.primaryKey] = { name: props.primaryKey, type: graphql_1.GraphQLString };
            args[props.rangeKey] = { name: props.rangeKey, type: graphql_1.GraphQLString };
            return args;
        },
        getEntryListQuery: (dictKey) => {
            const fields = entryProps.createEntryFields();
            //console.log("fields: ", fields);
            return datalayer_libs_1.getEntryListQuery(props.id, dictKey, fields);
        },
        setEntryMutation: (values) => {
            const fields = entryProps.createEntryFields();
            //console.log("fields: ", fields);
            return datalayer_libs_1.setEntryMutation(props.id, values, fields);
        },
        setEntry: (args, context, tableName) => {
            return datalayer_libs_1.setEntry(tableName, //"code-architect-dev-data-layer",
            props.primaryKey, // schema.Entry.ENTITY, //pkEntity
            args[props.primaryKey], // pkId
            props.rangeKey, //schema.Data.ENTITY, // skEntity
            args[props.rangeKey], // skId
            Object.keys(args).reduce((result, key) => {
                if (Object.keys(props.data).find(datakey => datakey === key) !== undefined) {
                    result[key] = args[key];
                }
                return result;
            }, {}) // jsonData
            );
        },
        listEntries: (args, context, tableName, key) => {
            const entity = key === "pk" ? props.primaryKey : props.rangeKey;
            const range = key === "pk" ? props.rangeKey : props.primaryKey;
            return datalayer_libs_1.ddbListEntries(tableName, //tablename
            key, // key
            entity, //entity
            args[entity], //value
            range //rangeEntity
            ).then(results => {
                console.log("promised: ", results);
                return results.map(item => {
                    const data = item.jsonData !== undefined ? JSON.parse(item.jsonData) : {};
                    data[props.primaryKey] = item.pk.substring(item.pk.indexOf("|") + 1);
                    data[props.rangeKey] = item.sk.substring(item.sk.indexOf("|") + 1);
                    return data;
                });
            });
        },
        middleware: middleware_component_1.default({ callback: (req, res, next) => {
                console.log("this is the mw of the entry: ", props.id);
                return next();
            } }),
        getPrimaryListQueryName: () => "list_" + props.id + "_" + props.primaryKey,
        getRangeListQueryName: () => "list_" + props.id + "_" + props.rangeKey,
        getSetMutationName: () => "set_" + props.id,
        /**
         * Returns whether this entry provides the query/mutation with the specified name
         * @param name
         */
        providesQuery: (name) => {
            const result = name === entryProps.getPrimaryListQueryName() ||
                name === entryProps.getRangeListQueryName() ||
                name === entryProps.getSetMutationName();
            //console.log("does ", props.id , " provide ", name, "? ", result)
            return result;
        }
    };
    return Object.assign({}, props, entryProps);
};
/**
 * an entry specifies a kind of data that can be stored in a line of the table
 */
exports.default = (props) => {
    // the component must have the properties of IComponent
    const componentProps = {
        infrastructureType: types_1.default.INFRASTRUCTURE_TYPE_COMPONENT,
        instanceType: exports.ENTRY_INSTANCE_TYPE,
        instanceId: props.id
    };
    return exports.createEntryProps(Object.assign({}, props, componentProps));
};
exports.isEntry = (component) => {
    return component !== undefined && component.instanceType === exports.ENTRY_INSTANCE_TYPE;
};
//# sourceMappingURL=entry-component.js.map