'use strict';

const request    = require('request-promise');
const readline   = require('readline');
const fs         = require('fs');
const _          = require('lodash');
const validator = require('validator');

if (process.argv[2] !== 'scan' && process.argv[2] !== 'remove') {
    console.log(`Please, specify operation that you'd like to launch {scan|remove} as second argument.`);
    return;
}

let requestData = {};

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const initialQuestion = (reqData) => {
    return new Promise((resolve, reject) => {
        rl.question('Enter url, where to search, please, use such format - (protocol//host e.g. https://google.com) - ', (answer) => {
            reqData.url = answer;
            resolve();
        });
    });
};

const question00 = (reqData) => {
    return new Promise((resolve, reject) => {
        rl.question('Type your login - ', (answer) => {
            reqData.login = answer;
            resolve();
        });
    });
};

const question01 = (reqData) => {
    return new Promise((resolve, reject) => {
        rl.question('Type your password - ', (answer) => {
            reqData.password = answer;
            resolve();
        });
    });
};

const question1 = (reqData) => {
    return new Promise((resolve, reject) => {
        rl.question('What is user username? Leave empty (hit Enter) if do not know - ', (answer) => {
            if (answer) {
                reqData.username = answer;
            }
            resolve();
        });
    });
};

const question2 = (reqData) => {
    return new Promise((resolve, reject) => {
        rl.question('What is user email? Leave empty (hit Enter) if do not know - ', (answer) => {
            if (answer) {
                reqData.email = answer;
            }
            resolve();
        });
    });
};

const question3 = (reqData) => {
    return new Promise((resolve, reject) => {
        rl.question('What is user firstName? Leave empty (hit Enter) if do not know - ', (answer) => {
            if (answer) {
                reqData.firstName = answer;
            }
            resolve();
        });
    });
};

const question4 = (reqData) => {
    return new Promise((resolve, reject) => {
        rl.question('What is user lastName? Leave empty (hit Enter) if do not know - ', (answer) => {
            if (answer) {
                reqData.lastName = answer;
            }
            resolve();
        });
    });
};

const question5 = (reqData) => {
    return new Promise((resolve, reject) => {
        rl.question('What is user fullName? Leave empty (hit Enter) if do not know - ', (answer) => {
            if (answer) {
                reqData.fullName = answer;
            }
            resolve();
        });
    });
};

const question6 = (reqData) => {
    return new Promise((resolve, reject) => {
        rl.question('What is user phone? Leave empty (hit Enter) if do not know - ', (answer) => {
            if (answer) {
                reqData.phone = answer;
            }
            resolve();
        });
    });
};

const main = async (requestDataPrompt) => {
    if (process.argv[3] !== '-i') {
        await initialQuestion(requestDataPrompt);
        await question00(requestDataPrompt);
        await question01(requestDataPrompt);
        await question1(requestDataPrompt);
        await question2(requestDataPrompt);
        await question3(requestDataPrompt);
        await question4(requestDataPrompt);
        await question5(requestDataPrompt);
        await question6(requestDataPrompt);
        rl.close()
    } else {
        rl.close();

        const requestDataPath = process.argv[4] || null;
        if (fs.existsSync(requestDataPath)) {
            try {
                requestData = require(requestDataPath);
            } catch (err) {
                return Promise.reject('Please, specify correct path to json file with properties for request as argument.');
            }

            return Promise.resolve();
        }

        return Promise.reject('Please, specify correct path to json file with properties for request as argument.');
    }
};

main(requestData)
    .then(() => {
        if (_.isEmpty(requestData.url) || _.isEmpty(requestData.login) ||
            _.isEmpty(requestData.password || !validator.isURL(requestData.url, {require_protocol: true}))) {
            return Promise.reject('Url, login and password are required!');
        }

        if (_.isEmpty(requestData.username) && _.isEmpty(requestData.email) && _.isEmpty(requestData.firstName) &&
                _.isEmpty(requestData.lastName) && _.isEmpty(requestData.fullName) && _.isEmpty(requestData.phone)) {

            console.log('Response - {}');
            return Promise.resolve({});
        }

        const panamaApi = requestData.url.endsWith('/') ? requestData.url + 'api/v1.0/' : requestData.url + '/api/v1.0/';

        const authData = {login: requestData.login, password: requestData.password};
        requestData = _.omit(requestData, ['login', 'password', 'url']);


        const pdpScanUrl = panamaApi + 'util/pdp_scan';
        const pdpRemoveUrl = panamaApi + 'util/pdp_remove';

        let pdpUrl = '';

        if (process.argv[2] === 'scan') {
            pdpUrl = pdpScanUrl;
        } else {
            pdpUrl = pdpRemoveUrl;
        }

        return request.put(pdpUrl,
            {
                headers: {
                    'Content-Type': 'application/json'
                },
                auth: {
                    'user': authData.login,
                    'pass': authData.password,
                },
                body: requestData,
                json: true,
                rejectUnauthorized: false,
                timeout: 30000
            });
    })
    .then((result) => {
        if (_.isEmpty(result)) {
            console.log(JSON.stringify(result, null, 4));
        } else {
            console.log('Records found with specified Personal Data');
            if (result.users && result.users.length > 0) {
                console.log('\tUsers:');
                result.users.forEach((user) => {
                    let userOutput = '\t\t';
                    if (user.username) {
                        userOutput += 'Username = ' + user.username;
                    }
                    if (user.email) {
                        userOutput += ', Email = ' + user.email;
                    }
                    if (user.firstName) {
                        userOutput += ', First Name = ' + user.firstName;
                    }
                    if (user.lastName) {
                        userOutput += ', Last Name = ' + user.lastName;
                    }
                    if (user.phone) {
                        userOutput += ', Phone = ' + user.phone;
                    }
                    console.log(userOutput);
                });
            }

            if (result.profiles && result.profiles.length > 0) {
                console.log('\tAccounts:');
                result.profiles.forEach((profile) => {
                    let profileOutput = '\t\t';
                    if (profile.app) {
                        profileOutput += 'Connector = ' + profile.app;
                    }
                    if (profile.username) {
                        profileOutput += ', Username = ' + profile.username;
                    }

                    console.log(profileOutput);
                });
            }

            if (result.flows && result.flows.length > 0) {
                console.log('\tFlows:');
                result.flows.forEach((flow) => {
                    let flowOutput = '\t\t';
                    if (flow.title) {
                        flowOutput += 'Title = ' + flow.title;
                    }
                    if (flow.description) {
                        flowOutput += ', Description = ' + flow.description;
                    }
                    console.log(flowOutput);

                    if (flow.comments && flow.comments.length > 0) {
                        console.log('\t\t\tComments:');
                        flow.comments.forEach((comment) => {
                            let commentOutput = '\t\t\t\t';
                            if (comment.user) {
                                commentOutput += 'User = ' + comment.user;
                            }
                            if (comment.text) {
                                commentOutput += ', Text = ' + comment.text;
                            }
                            console.log(commentOutput);
                        });
                    }

                    if (flow.conditions && flow.conditions.length > 0) {
                        console.log('\t\t\tConditions:');
                        flow.conditions.forEach((condition) => {
                            let conditionOutput = '\t\t\t\t';
                            if (condition.field) {
                                conditionOutput += 'Field = ' + condition.field;
                            }
                            if (condition.value) {
                                conditionOutput += ', Value = ' + condition.value;
                            }
                            console.log(conditionOutput);
                        });
                    }

                    if (flow.mappings && flow.mappings.length > 0) {
                        console.log('\t\t\tMappings:');
                        flow.mappings.forEach((mapping) => {
                            let mappingOutput = '\t\t\t\t';
                            if (mapping.field) {
                                mappingOutput += 'Field = ' + mapping.field;
                            }
                            if (!mapping.field && mapping.value) {
                                mappingOutput += 'Value = ' + mapping.value;
                            }
                            if (mapping.field && mapping.value) {
                                mappingOutput += ', Value = ' + mapping.value;
                            }
                            console.log(mappingOutput);
                        });
                    }
                });
            }

            if (result.configs && result.configs.length > 0) {
                console.log('\tConfigurations:');
                result.configs.forEach((config) => {
                    let configOutput = '\t\t';
                    if (config.app) {
                        configOutput += 'Connector = ' + config.app;
                    }
                    if (config.name) {
                        configOutput += ', Name = ' + config.name;
                    }
                    if (config.description) {
                        configOutput += ', Description = ' + config.description;
                    }
                    console.log(configOutput);
                });
            }
        }
    })
    .catch((err) => {
        if (err.message) {
            console.log('Error - ', err.message);
        } else {
            console.log('Error - ', err);
        }
    });
