"use strict";
/**
 * This plugin adds the following libraries to the requirements:
 *
 * - GraphQL: npm install --save apollo-client apollo-cache-inmemory apollo-link-http graphql-tag graphql
 * - React Apollo: npm install --save react-apollo
 * //- isomorphic-fetch: npm install --save isomorphic-fetch es6-promise
 * - AWS SDK: npm install --save aws-sdk
 *
 *
 */
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 __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const plugin_1 = require("../libs/plugin");
const datalayer_component_1 = require("./datalayer-component");
const deepmerge = __importStar(require("deepmerge"));
const parser_1 = require("../libs/parser");
/**
 * The Data
 *
 * @param props
 */
exports.DataLayerPlugin = (props) => {
    const path = require('path');
    const result = {
        applies: (component) => {
            return datalayer_component_1.isDataLayer(component);
        },
        // convert the component into configuration parts
        // while the component is of Type `any`, its props must be of type `IDataLayerArgs` | `IDataLayerProps`
        process: (component, childConfigs, infrastructureMode) => {
            const dbPath = path.join(require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").currentAbsolutePath(), ".dynamodb");
            // the datalayer has a (query) server application
            /*const queryWebPack = (args) => require("../../../infrastructure-scripts/dist/infra-comp-utils/webpack-libs").complementWebpackConfig(
                require("../../../infrastructure-scripts/dist/infra-comp-utils/webpack-libs").createServerWebpackConfig(
                    "./"+path.join("node_modules", "infrastructure-components", "dist" , "assets", "data-layer.js"), //entryPath: string,
                    path.join(require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").currentAbsolutePath(), props.buildPath), //use the buildpath from the parent plugin
                    component.id, // name of the server

                    // aliasesDict
                    {
                        __CONFIG_FILE_PATH__: require("../../../infrastructure-scripts/dist/infra-comp-utils/system-libs").pathToConfigFile(props.configFilePath), // replace the IsoConfig-Placeholder with the real path to the main-config-bundle

                        
                    },

                    // replacementsDict
                    {
                        __DATALAYER_ID__: `"${component.id}"`,

                        /*,
                        __ASSETS_PATH__: `"${component.assetsPath}"`,
                        __RESOLVED_ASSETS_PATH__: `"${resolveAssetsPath(
                            component.buildPath,
                            serverName,
                            component.assetsPath )
                            }"`* /
                    }
                )
            );*/
            /**
             * setup a database and a handler
             */
            const dataLayerConfig = {
                /*functions: {

                    /*
                    query: {
                        // index.default refers to the default export of the file, points to the output of the queryWebpack-bundle
                        handler: path.join(props.buildPath, component.id, `${component.id}.default`),
                        role: "DataLayerLambdaRole",
                        events: [
                            {
                                http: {
                                    //this path must match the path specified in the environment below
                                    path: "query",

                                    // the Apollo Api usually works via POST, mutations always use POST
                                    method: "POST",

                                    cors: "true"
                                }
                            },
                        ]
                    }

                },*/
                plugins: ["serverless-dynamodb-local"],
                /* see: https://www.npmjs.com/package/serverless-dynamodb-local */
                custom: {
                    "dynamodb": {
                        stages: ["${self:provider.stage}", "dev"],
                        start: {
                            port: 8000,
                            //inMemory: "true",
                            dbPath: dbPath,
                            heapInitial: "200m",
                            heapMax: "1g",
                            migrate: "true",
                            //seed: "true",
                            convertEmptyValues: "true",
                        },
                    }
                },
                provider: {
                    environment: {
                        // set the table name in an environment variable
                        TABLE_NAME: "${self:service}-${self:provider.stage, env:STAGE, 'dev'}-data-layer",
                        // must match the http-path from the function-event
                        GRAPHQL_PATH: "query"
                    }
                },
                resources: {
                    Resources: {
                        ApplicationDynamoDBTable: {
                            Type: "AWS::DynamoDB::Table",
                            Properties: {
                                TableName: "${self:service}-${self:provider.stage, env:STAGE, 'dev'}-data-layer",
                                BillingMode: "PAY_PER_REQUEST",
                                AttributeDefinitions: [
                                    {
                                        AttributeName: "pk",
                                        AttributeType: "S"
                                    }, {
                                        AttributeName: "sk",
                                        AttributeType: "S"
                                    }
                                ],
                                KeySchema: [
                                    {
                                        AttributeName: "pk",
                                        KeyType: "HASH"
                                    }, {
                                        AttributeName: "sk",
                                        KeyType: "RANGE"
                                    }
                                ],
                                GlobalSecondaryIndexes: [
                                    {
                                        IndexName: "reverse",
                                        KeySchema: [
                                            {
                                                AttributeName: "sk",
                                                KeyType: "HASH"
                                            }, {
                                                AttributeName: "pk",
                                                KeyType: "RANGE"
                                            }
                                        ],
                                        Projection: {
                                            ProjectionType: "ALL"
                                        }
                                    }
                                ]
                            }
                        }
                    }
                }
            };
            function createLocalDbFolder() {
                return __awaiter(this, void 0, void 0, function* () {
                    //console.log("check for >>copyAssetsPostBuild<<");
                    const fs = require('fs');
                    if (props.parserMode == parser_1.PARSER_MODES.MODE_BUILD) {
                        if (!fs.existsSync(dbPath)) {
                            console.log("creating folder: ", dbPath);
                            fs.mkdirSync(dbPath, { recursive: true });
                            yield require("../../../infrastructure-scripts/dist/infra-comp-utils/sls-libs").runSlsCmd("sls dynamodb install", data => {
                                console.log(data);
                            });
                        }
                    }
                });
            }
            ;
            const iamRoleStatements = [
                {
                    Effect: "Allow",
                    Action: [
                        "dynamodb:GetItem",
                        "dynamodb:UpdateItem",
                        "dynamodb:DeleteItem",
                        "dynamodb:PutItem",
                        "dynamodb:Scan",
                        "dynamodb:Query"
                    ],
                    Resource: [
                        '"arn:aws:dynamodb:${self:provider.region}:*:table/${self:service}-${self:provider.stage, env:STAGE, \'dev\'}-data-layer"',
                        '"arn:aws:dynamodb:${self:provider.region}:*:table/${self:service}-${self:provider.stage, env:STAGE, \'dev\'}-data-layer/*"'
                    ]
                }
            ].concat(plugin_1.forwardChildIamRoleStatements(childConfigs));
            //console.log("datalayer iamStatements: ", iamRoleStatements);
            return {
                slsConfigs: deepmerge.all([
                    dataLayerConfig
                ].concat(childConfigs.map(config => config.slsConfigs))),
                // forward the webpacks (of the WebApps) as-is, add the queryApp-Webpack-bundle
                webpackConfigs: /*[queryWebPack].concat(*/ plugin_1.forwardChildWebpackConfigs(childConfigs).map(
                // complement the args with the datalayer-id
                fWp => (args) => fWp(Object.assign({ datalayerid: component.id }, args))) /*)*/,
                postBuilds: childConfigs.reduce((result, config) => result.concat(config.postBuilds), [createLocalDbFolder]),
                iamRoleStatements: iamRoleStatements
            };
        }
    };
    return result;
};
//# sourceMappingURL=datalayer-plugin.js.map