/**
 * Copyright JS Foundation and other contributors, http://js.foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/

RED.projects.userSettings = (function() {

    var gitUsernameInput;
    var gitEmailInput;

    function createGitUserSection(pane) {

        var currentGitSettings = RED.settings.get('git') || {};
        currentGitSettings.user = currentGitSettings.user || {};

        var title = $('<h3></h3>').text("Committer Details").appendTo(pane);

        var gitconfigContainer = $('<div class="user-settings-section"></div>').appendTo(pane);
        $('<div style="color:#aaa;"></div>').appendTo(gitconfigContainer).text("Leave blank to use system default");

        var row = $('<div class="user-settings-row"></div>').appendTo(gitconfigContainer);
        $('<label for=""></label>').text('Username').appendTo(row);
        gitUsernameInput = $('<input type="text">').appendTo(row);
        gitUsernameInput.val(currentGitSettings.user.name||"");

        row = $('<div class="user-settings-row"></div>').appendTo(gitconfigContainer);
        $('<label for=""></label>').text('Email').appendTo(row);
        gitEmailInput = $('<input type="text">').appendTo(row);
        gitEmailInput.val(currentGitSettings.user.email||"");
    }


    function createSSHKeySection(pane) {
        var container = $('<div class="user-settings-section"></div>').appendTo(pane);
        var popover;
        var title = $('<h3></h3>').text("SSH Keys").appendTo(container);
        var subtitle = $('<div style="color:#aaa;"></div>').appendTo(container).text("Allows you to create secure connections to remote git repositories.");

        var addKeyButton = $('<button id="user-settings-gitconfig-add-key" class="editor-button editor-button-small" style="float: right; margin-right: 10px;">add key</button>')
            .appendTo(subtitle)
            .click(function(evt) {
                addKeyButton.attr('disabled',true);
                saveButton.attr('disabled',true);
                // bg.children().removeClass("selected");
                // addLocalButton.click();
                addKeyDialog.slideDown(200);
                keyNameInput.focus();
            });

        var validateForm = function() {
            var valid = /^[a-zA-Z0-9\-_]+$/.test(keyNameInput.val());
            keyNameInput.toggleClass('input-error',keyNameInputChanged&&!valid);

            // var selectedButton = bg.find(".selected");
            // if (selectedButton[0] === addLocalButton[0]) {
            //     valid = valid && localPublicKeyPathInput.val().length > 0 && localPrivateKeyPathInput.val().length > 0;
            // } else if (selectedButton[0] === uploadButton[0]) {
            //     valid = valid && publicKeyInput.val().length > 0 && privateKeyInput.val().length > 0;
            // } else if (selectedButton[0] === generateButton[0]) {
                var passphrase = passphraseInput.val();
                var validPassphrase = passphrase.length === 0 || passphrase.length >= 8;
                passphraseInput.toggleClass('input-error',!validPassphrase);
                if (!validPassphrase) {
                    passphraseInputSubLabel.text("Passphrase too short");
                } else if (passphrase.length === 0) {
                    passphraseInputSubLabel.text("Optional");
                } else {
                    passphraseInputSubLabel.text("");
                }
                valid = valid && validPassphrase;
            // }

            saveButton.attr('disabled',!valid);

            if (popover) {
                popover.close();
                popover = null;
            }
        };

        var row = $('<div class="user-settings-row"></div>').appendTo(container);
        var addKeyDialog = $('<div class="projects-dialog-list-dialog"></div>').hide().appendTo(row);
        $('<div class="projects-dialog-list-dialog-header">').text('Add SSH Key').appendTo(addKeyDialog);
        var addKeyDialogBody = $('<div>').appendTo(addKeyDialog);

        row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
        $('<div style="color:#aaa;"></div>').appendTo(row).text("Generate a new public/private key pair");
        // var bg = $('<div></div>',{class:"button-group", style:"text-align: center"}).appendTo(row);
        // var addLocalButton = $('<button class="editor-button toggle selected">use local key</button>').appendTo(bg);
        // var uploadButton = $('<button class="editor-button toggle">upload key</button>').appendTo(bg);
        // var generateButton = $('<button class="editor-button toggle">generate key</button>').appendTo(bg);
        // bg.children().click(function(e) {
        //     e.preventDefault();
        //     if ($(this).hasClass("selected")) {
        //         return;
        //     }
        //     bg.children().removeClass("selected");
        //     $(this).addClass("selected");
        //     if (this === addLocalButton[0]) {
        //         addLocalKeyPane.show();
        //         generateKeyPane.hide();
        //         uploadKeyPane.hide();
        //     } else if (this === uploadButton[0]) {
        //         addLocalKeyPane.hide();
        //         generateKeyPane.hide();
        //         uploadKeyPane.show();
        //     } else if (this === generateButton[0]){
        //         addLocalKeyPane.hide();
        //         generateKeyPane.show();
        //         uploadKeyPane.hide();
        //     }
        //     validateForm();
        // })


        row = $('<div class="user-settings-row"></div>').appendTo(addKeyDialogBody);
        $('<label for=""></label>').text('Name').appendTo(row);
        var keyNameInputChanged = false;
        var keyNameInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
            keyNameInputChanged = true;
            validateForm();
        });
        $('<label class="projects-edit-form-sublabel"><small>Must contain only A-Z 0-9 _ -</small></label>').appendTo(row).find("small");

        var generateKeyPane = $('<div>').appendTo(addKeyDialogBody);
        row = $('<div class="user-settings-row"></div>').appendTo(generateKeyPane);
        $('<label for=""></label>').text('Passphrase').appendTo(row);
        var passphraseInput = $('<input type="password">').appendTo(row).on("change keyup paste",validateForm);
        var passphraseInputSubLabel = $('<label class="projects-edit-form-sublabel"><small>Optional</small></label>').appendTo(row).find("small");

        // var addLocalKeyPane = $('<div>').hide().appendTo(addKeyDialogBody);
        // row = $('<div class="user-settings-row"></div>').appendTo(addLocalKeyPane);
        // $('<label for=""></label>').text('Public key').appendTo(row);
        // var localPublicKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm);
        // $('<label class="projects-edit-form-sublabel"><small>Public key file path, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small");
        // row = $('<div class="user-settings-row"></div>').appendTo(addLocalKeyPane);
        // $('<label for=""></label>').text('Private key').appendTo(row);
        // var localPrivateKeyPathInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm);
        // $('<label class="projects-edit-form-sublabel"><small>Private key file path, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small");
        //
        // var uploadKeyPane = $('<div>').hide().appendTo(addKeyDialogBody);
        // row = $('<div class="user-settings-row"></div>').appendTo(uploadKeyPane);
        // $('<label for=""></label>').text('Public key').appendTo(row);
        // var publicKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm);
        // $('<label class="projects-edit-form-sublabel"><small>Paste in public key contents, for example: ~/.ssh/id_rsa.pub</small></label>').appendTo(row).find("small");
        // row = $('<div class="user-settings-row"></div>').appendTo(uploadKeyPane);
        // $('<label for=""></label>').text('Private key').appendTo(row);
        // var privateKeyInput = $('<textarea>').appendTo(row).on("change keyup paste",validateForm);
        // $('<label class="projects-edit-form-sublabel"><small>Paste in private key contents, for example: ~/.ssh/id_rsa</small></label>').appendTo(row).find("small");




        var hideEditForm = function() {
            addKeyButton.attr('disabled',false);
            addKeyDialog.hide();

            keyNameInput.val("");
            keyNameInputChanged = false;
            passphraseInput.val("");
            // localPublicKeyPathInput.val("");
            // localPrivateKeyPathInput.val("");
            // publicKeyInput.val("");
            // privateKeyInput.val("");
            if (popover) {
                popover.close();
                popover = null;
            }
        }
        var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>').appendTo(addKeyDialog);
        $('<button class="editor-button">Cancel</button>')
            .appendTo(formButtons)
            .click(function(evt) {
                evt.preventDefault();
                hideEditForm();
            });
        var saveButton = $('<button class="editor-button">Generate key</button>')
            .appendTo(formButtons)
            .click(function(evt) {
                evt.preventDefault();
                var spinner = utils.addSpinnerOverlay(addKeyDialog).addClass('projects-dialog-spinner-contain');
                var payload = {
                    name: keyNameInput.val()
                };

                // var selectedButton = bg.find(".selected");
                // if (selectedButton[0] === addLocalButton[0]) {
                //     payload.type = "local";
                //     payload.publicKeyPath = localPublicKeyPathInput.val();
                //     payload.privateKeyPath = localPrivateKeyPathInput.val();
                // } else if (selectedButton[0] === uploadButton[0]) {
                //     payload.type = "upload";
                //     payload.publicKey = publicKeyInput.val();
                //     payload.privateKey = privateKeyInput.val();
                // } else if (selectedButton[0] === generateButton[0]) {
                    payload.type = "generate";
                    payload.comment = gitEmailInput.val();
                    payload.password = passphraseInput.val();
                    payload.size = 4096;
                // }
                var done = function(err) {
                    spinner.remove();
                    if (err) {
                        return;
                    }
                    hideEditForm();
                }
                // console.log(JSON.stringify(payload,null,4));
                RED.deploy.setDeployInflight(true);
                utils.sendRequest({
                    url: "settings/user/keys",
                    type: "POST",
                    responses: {
                        0: function(error) {
                            done(error);
                        },
                        200: function(data) {
                            refreshSSHKeyList(payload.name);
                            done();
                        },
                        400: {
                            'unexpected_error': function(error) {
                                console.log(error);
                                done(error);
                            }
                        },
                    }
                },payload);
            });

        row = $('<div class="user-settings-row projects-dialog-list"></div>').appendTo(container);
        var emptyItem = { empty: true };
        var expandKey = function(container,entry) {
            var row = $('<div class="projects-dialog-ssh-public-key">',{style:"position:relative"}).appendTo(container);
            var keyBox = $('<pre>',{style:"min-height: 80px"}).appendTo(row);
            var spinner = utils.addSpinnerOverlay(keyBox).addClass('projects-dialog-spinner-contain');
            var options = {
                url: 'settings/user/keys/'+entry.name,
                type: "GET",
                responses: {
                    200: function(data) {
                        keyBox.text(data.publickey);
                        spinner.remove();
                    },
                    400: {
                        'unexpected_error': function(error) {
                            console.log(error);
                            spinner.remove();
                        }
                    },
                }
            }
            utils.sendRequest(options);

            var formButtons = $('<span class="button-row" style="position: relative; float: right; margin: 10px;"></span>').appendTo(row);
            $('<button class="editor-button editor-button-small">Copy public key to clipboard</button>')
                .appendTo(formButtons)
                .click(function(evt) {
                    try {
                        evt.stopPropagation();
                        evt.preventDefault();
                        document.getSelection().selectAllChildren(keyBox[0]);
                        var ret = document.execCommand('copy');
                        document.getSelection().empty();
                    } catch(err) {

                    }

                });

            return row;
        }
        var keyList = $('<ol class="projects-dialog-ssh-key-list">').appendTo(row).editableList({
            height: 'auto',
            addButton: false,
            scrollOnAdd: false,
            addItem: function(row,index,entry) {
                var container = $('<div class="projects-dialog-list-entry">').appendTo(row);
                if (entry.empty) {
                    container.addClass('red-ui-search-empty');
                    container.text("No SSH keys");
                    return;
                }
                var topRow = $('<div class="projects-dialog-ssh-key-header">').appendTo(container);
                $('<span class="entry-icon"><i class="fa fa-key"></i></span>').appendTo(topRow);
                $('<span class="entry-name">').text(entry.name).appendTo(topRow);
                var tools = $('<span class="button-row entry-tools">').appendTo(topRow);
                var expandedRow;
                topRow.click(function(e) {
                    if (expandedRow) {
                        expandedRow.slideUp(200,function() {
                            expandedRow.remove();
                            expandedRow = null;
                        })
                    } else {
                        expandedRow = expandKey(container,entry);
                    }
                    })
                if (!entry.system) {
                    $('<button class="editor-button editor-button-small"><i class="fa fa-trash"></i></button>')
                        .appendTo(tools)
                        .click(function(e) {
                            e.stopPropagation();
                            var spinner = utils.addSpinnerOverlay(row).addClass('projects-dialog-spinner-contain');
                            var notification = RED.notify("Are you sure you want to delete the SSH key '"+entry.name+"'? This cannot be undone.", {
                                type: 'warning',
                                modal: true,
                                fixed: true,
                                buttons: [
                                    {
                                        text: RED._("common.label.cancel"),
                                        click: function() {
                                            spinner.remove();
                                            notification.close();
                                        }
                                    },
                                    {
                                        text: "Delete key",
                                        click: function() {
                                            notification.close();
                                            var url = "settings/user/keys/"+entry.name;
                                            var options = {
                                                url: url,
                                                type: "DELETE",
                                                responses: {
                                                    200: function(data) {
                                                        row.fadeOut(200,function() {
                                                            keyList.editableList('removeItem',entry);
                                                            setTimeout(spinner.remove, 100);
                                                            if (keyList.editableList('length') === 0) {
                                                                keyList.editableList('addItem',emptyItem);
                                                            }
                                                        });
                                                    },
                                                    400: {
                                                        'unexpected_error': function(error) {
                                                            console.log(error);
                                                            spinner.remove();
                                                        }
                                                    },
                                                }
                                            }
                                            utils.sendRequest(options);
                                        }
                                    }
                                ]
                            });
                        });
                }
                if (entry.expand) {
                    expandedRow = expandKey(container,entry);
                }
            }
        });

        var refreshSSHKeyList = function(justAdded) {
            $.getJSON("settings/user/keys",function(result) {
                if (result.keys) {
                    result.keys.sort(function(A,B) {
                        return A.name.localeCompare(B.name);
                    });
                    keyList.editableList('empty');
                    result.keys.forEach(function(key) {
                        if (key.name === justAdded) {
                            key.expand = true;
                        }
                        keyList.editableList('addItem',key);
                    });
                    if (keyList.editableList('length') === 0) {
                        keyList.editableList('addItem',emptyItem);
                    }

                }
            })
        }
        refreshSSHKeyList();

    }

    function createSettingsPane(activeProject) {
        var pane = $('<div id="user-settings-tab-gitconfig" class="project-settings-tab-pane node-help"></div>');
        createGitUserSection(pane);
        createSSHKeySection(pane);
        return pane;
    }

    var utils;
    function init(_utils) {
        utils = _utils;
        RED.userSettings.add({
            id:'gitconfig',
            title: "Git config", // TODO: nls
            get: createSettingsPane,
            close: function() {
                var currentGitSettings = RED.settings.get('git') || {};
                currentGitSettings.user = currentGitSettings.user || {};
                currentGitSettings.user.name = gitUsernameInput.val();
                currentGitSettings.user.email = gitEmailInput.val();
                RED.settings.set('git', currentGitSettings);
            }
        });
    }

    return {
        init: init,
    };
})();