const config = require('../bin/config');

const request = require('request-promise-native');
const APIURL = !process.env.RANIENV ? 'https://api-cli.sshchain.com.br' : 'http://localhost:3038';

class API {

    static create(...args) {
        return new API(...args);
    }

    constructor() {
        
        this.wordSearch = null;

        this._req = request.defaults({
            method: 'POST',
            baseUrl: APIURL,
            json: true,
            headers: {
                'Cache-Control': 'no-cache'
            }
        });
    }

    getForConnect(serverAlias) {
        const ops = {
            method: 'GET',
            uri: `/chain/connect`,
            qs: {
                alias: serverAlias
            },
            body: {}
        };
        return this.req(ops);
    }

    getKeys() {
        const ops = {
            method: 'GET',
            uri: `/chain/pem`,
            body: {}
        };
        return this.req(ops);
    }

    deleteKey(keyAliasOrId) {
        const ops = {
            method: 'DELETE',
            uri: `/chain/pem`,
            body: {
                key: keyAliasOrId
            }
        };
        return this.req(ops);
    }

    newKey(nameFile, privateFile, privateKeyPassword = null, publicFile = null) {
        const ops = {
            method: 'POST',
            uri: `/chain/pem`,
            body: {
                pv: privateFile,
                pb: publicFile,
                name: nameFile,
                pass: privateKeyPassword
            }
        };
        return this.req(ops);
    }

    listKeys(group = null) {
        const ops = {
            method: 'GET',
            uri: `/chain/pem`,
            qs: {
                group: group,
                search: this.wordSearch || null
            }
        };
        return this.req(ops);
    }

    linkKey(keyAlias, target = {}) {
        const ops = {
            method: 'POST',
            uri: `/chain/pem/link`,
            body: Object.assign(target, { key: keyAlias })
        };
        return this.req(ops);
    }

    unlinkKey(serverAlias = null, groupName = null) {
        const ops = {
            method: 'POST',
            uri: `/chain/pem/unlink`,
            body: {
                server: serverAlias,
                group: groupName
            }
        };
        return this.req(ops);
    }

    listServers(group = null) {
        const ops = {
            method: 'GET',
            uri: `/chain/server`,
            qs: {
                group: group,
                search: this.wordSearch || null
            }
        };
        return this.req(ops);
    }

    newServer(body) {
        const ops = {
            method: 'POST',
            uri: `/chain/server`,
            body: body
        };
        return this.req(ops);
    }

    deleteServer(idOrAlias) {
        const ops = {
            method: 'DELETE',
            uri: `/chain/server`,
            body: {
                key: idOrAlias
            }
        };
        return this.req(ops);
    }

    getGroups() {
        const ops = {
            method: 'GET',
            uri: `/chain/group`,
            body: {}
        };
        return this.req(ops);
    }

    listGroups() {
        const ops = {
            method: 'GET',
            uri: `/chain/group`,
            qs: {
                search: this.wordSearch || null
            }
        };
        return this.req(ops);
    }

    newGroup(options) {
        const ops = {
            method: 'POST',
            uri: `/chain/group`,
            body: options
        };
        return this.req(ops);
    }

    deleteGroup(idOrAlias) {
        const ops = {
            method: 'DELETE',
            uri: `/chain/group`,
            body: {
                key: idOrAlias
            }
        };
        return this.req(ops);
    }

    linkGroup(groupName, serverAlias) {
        const ops = {
            method: 'POST',
            uri: `/chain/group/link`,
            body: {
                group: groupName,
                server: serverAlias
            }
        };
        return this.req(ops);
    }

    unlinkGroup(serverAlias = null) {
        const ops = {
            method: 'POST',
            uri: `/chain/group/unlink`,
            body: {
                server: serverAlias
            }
        };
        return this.req(ops);
    }

    search(word) {
        if(word) this.wordSearch = word;
        return this;
    }

    checkConnection() {
        return new Promise((resolve, reject) => {
            require('dns').lookup('api-cli.sshchain.com.br',err => {
                if (err && err.code == "ENOTFOUND")
                    resolve(false);
                else
                    resolve(true);
            })
        })
    }

    req(ops, useToken = true) {

        if(useToken && config.has('tokenData.accessToken')) {
            if(!ops.headers) ops.headers = {};
            ops.headers['accessToken'] = config.get('tokenData.accessToken');
        }

        return this._req(ops);
    }
    
}

module.exports = API.create();