/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

define([
    'underscore', 'backbone', 'jquery',
    'brooklyn-utils', 'model/location',
    'text!tpl/location-wizard/modal.html',
    'text!tpl/location-wizard/location-type.html',
    'text!tpl/location-wizard/location-configuration.html',
    'text!tpl/location-wizard/location-provisioning.html',
    'text!tpl/location-wizard/location-provisioning-entry.html',

    'jquery-easy-autocomplete'
], function(_, Backbone, $, Util, Location, ModalHtml, LocationTypeHtml, LocationConfigurationHtml, LocationProvisioningHtml, LocationProvisioningEntry) {
    var _YAML_HEADER = [
        'brooklyn.catalog:',
        '  version: 0.0.1',
        '  items:'
    ];

    var Wizard = Backbone.View.extend({
        template: _.template(ModalHtml),
        events: {
            'click .location-wizard-previous': 'previousStep',
            'click .location-wizard-next': 'nextStep',
            'click .location-wizard-edit': 'edit',
            'click .location-wizard-save': 'save',
            'click .location-wizard-save-and-reset': 'saveAndReset'
        },

        initialize: function () {
            this.type = '';
            this.step = 0;
            this.location = new Location.Model;
            this.onLocationCreated = _.isFunction(this.options.onLocationCreated) ? this.options.onLocationCreated : undefined;
            this.onFinish = _.isFunction(this.options.onFinish) ? this.options.onFinish : undefined;
            this.className = _.isBoolean(this.options.isModal) && this.options.isModal ? 'modal hide fade' : '';

            this.steps = [
                {
                    title: 'Location Type',
                    subtitle: 'Select the location type to make available for deployments',
                    view: LocationType
                },
                {
                    title: '<%= type %> Location - Configuration',
                    view: LocationConfiguration
                },
                {
                    title: '<%= type %> Location - Provisioning',
                    subtitle: 'In many target locations, additional configuration may be supported. Enter any such options here. For information on available options consult the <a href="https://brooklyn.apache.org/v/latest/ops/locations/">Brooklyn documentation</a>. Alternatively you can skip this step.',
                    view: LocationProvisioning
                }
            ];

            this.actions = [
                {
                    label: 'Edit in YAML',
                    class: 'location-wizard-edit'
                },
                {
                    label: 'Save and Add Another',
                    class: 'location-wizard-save-and-reset'
                },
                {
                    label: 'Save',
                    class: 'location-wizard-save'
                }
            ];
        },

        render: function() {
            this.$el.addClass(this.className).html(this.template({}));

            this.renderStep();

            return this;
        },

        renderStep: function() {
            var step = this.steps[this.step];

            this.$('.location-wizard-title').html(_.template(step.title)({type: this.capitalize(this.type)}));
            if (_.has(step, 'subtitle')) {
                this.$('.location-wizard-subtitle').html(_.template(step.subtitle)({type: this.type})).show();
            } else {
                this.$('.location-wizard-subtitle').hide();
            }

            // Render actions buttons
            var actionContainer = this.$('.location-wizard-actions').empty();
            if (this.step === 2 || (this.type === 'byon' && this.step === 1)) {
                _.each(this.actions, function(element, index, list) {
                    actionContainer.append($('<button>').addClass('btn btn-mini btn-info location-wizard-action ' + element.class).html(element.label));
                });
            }

            if (this.currentView) {
                this.currentView.close();
            }

            if (_.isObject(step.view)) {
                this.currentView = new step.view({wizard: this});
                this.$('.modal-body').html(this.currentView.render().el);
            }

            // Render prev / next buttons
            var prev =  this.$('.location-wizard-previous');
            var next =  this.$('.location-wizard-next');
            if (this.step == 0) {
                prev.hide();
            } else {
                prev.show();
            }
            if (this.step == this.steps.length - 1) {
                next.hide();
            } else if (this.step == this.steps.length - 2 && this.type === 'byon') {
                next.hide();
            } else {
                next.show();
            }

            this.$('input').first().focus();
        },

        previousStep: function() {
            if (this.step > 0) {
                this.step--;
                this.renderStep();
            }
        },

        nextStep: function() {
            if (this.step < this.steps.length - 1) {
                this.step++;
                this.renderStep();
            }
        },

        enableNextAction: function(enabled) {
            if (enabled) {
                this.$('.location-wizard-action').removeAttr('disabled');
            } else {
                this.$('.location-wizard-action').attr('disabled', 'disabled');
            }
        },

        capitalize: function(text) {
            return text && text.charAt(0).toUpperCase() + text.slice(1);
        },

        edit: function() {
            if (this.currentView instanceof LocationProvisioning) {
                this.currentView.setProvisioningProperties();
            }

            var baseSpacing = '  ';

            var content = [].concat(_YAML_HEADER);

            content.push(baseSpacing + '- id: ' + this.location.get('name'));

            baseSpacing += '  ';
            content.push(baseSpacing + 'itemType: location');
            content.push(baseSpacing + 'item:');

            baseSpacing += '  ';
            content.push(baseSpacing + 'type: ' + this.location.get('spec'));

            var config = this.location.get('config');
            if (_.keys(config).length > 0) {
                content.push(baseSpacing + 'brooklyn.config:');
                baseSpacing += '  ';

                _.each(config, function(value, key) {
                    if (_.isArray(value)) {
                        content.push(baseSpacing + key + ':');
                        _.each(value, function(valueValue) {
                            content.push(baseSpacing + '- ' + valueValue);
                        });
                    } else if (_.isObject(value)) {
                        content.push(baseSpacing + key + ':');
                        _.each(value, function(valueValue, valueKey) {
                            content.push(baseSpacing + '  ' + valueKey + ': ' + valueValue);
                        });
                    } else {
                        content.push(baseSpacing + key + ': ' + value);
                    }
                });
            }

            Backbone.history.navigate("/v1/editor/catalog/_/"+ encodeURIComponent(content.join("\n")), {trigger: true});
        },

        save: function(callback) {
            var that = this;

            if (this.currentView instanceof LocationProvisioning) {
                this.currentView.setProvisioningProperties();
            }

            this.location.save()
                .done(function (data) {
                    if (_.isFunction(that.onLocationCreated)) {
                        that.onLocationCreated(that, data);
                    }

                    if (_.isFunction(callback)) {
                        callback();
                    } else if (_.isFunction(that.onFinish)) {
                        that.onFinish(that, data);
                    }
                })
                .fail(function (response) {
                    that.showFailure(Util.extractError(response));
                });
        },

        saveAndReset: function() {
            var that = this;
            this.save(function() {
                that.step = 0;
                that.type = '';
                that.location = new Location.Model;
                that.renderStep();
            });
        },

        showFailure: function(text) {
            if (!text) text = "Failure performing the specified action";
            this.$('div.error-message .error-message-text').html(_.escape(text));
            this.$('div.error-message').slideDown(250).delay(10000).slideUp(500);
        }

    });

    var LocationType = Backbone.View.extend({
        className: 'location-wizard-body',
        template: _.template(LocationTypeHtml),
        events: {
            'mouseenter .location-type': 'onDisplayHelp',
            'mouseleave .location-type': 'onHideHelp',
            'click .location-type': 'onSelectType'
        },

        wizard: null,

        initialize: function() {
            this.wizard = this.options.wizard;
        },

        render: function() {
            this.$el.html(this.template());

            this.wizard.enableNextAction(false);

            var that = this;
            this.$('.location-type').each(function () {
                if ($(this).data('type') === that.wizard.type) {
                    $(this).addClass('selected');
                    that.wizard.enableNextAction(true);
                }
            });

            return this;
        },

        onDisplayHelp: function(event) {
            var $elm = this.$(event.currentTarget);
            this.$('.help-text').html($elm.data('help')).show();
        },

        onHideHelp: function(event) {
            this.$('.help-text').html('').hide();
        },

        onSelectType: function(event) {
            var $elm = this.$(event.currentTarget);
            var type = $elm.data('type');

            $elm.toggleClass('selected');
            this.wizard.type = $elm.hasClass('selected') ? type : '';
            this.wizard.enableNextAction(this.wizard.type !== '');

            if (this.wizard.location.get('spec') !== this.wizard.type) {
                this.wizard.location = new Location.Model;
            }

            this.$('.location-type').each(function() {
                if ($(this).data('type') != type) {
                    $(this).removeClass('selected');
                }
            });

            return this;
        }
    });

    var common_fields = {
        location_id: {
            id: 'name',
            label: 'Location ID',
            type: 'text',
            help: 'A label to identify this location in YAML. Typically this is lower case using hyphens and no spaces',
            require: true
        },
        location_name: {
            id: 'displayName',
            label: 'Location Name',
            type: 'text',
            help: 'A display name to present this location to a user (optional)'
        },
    };
    
    var LocationConfiguration = Backbone.View.extend({
        className: 'location-wizard-body',
        template: _.template(LocationConfigurationHtml),
        events: {
            'blur input, textarea': 'onChange',
            'change select': 'onChange'
        },

        fields: {
            cloud: [
                common_fields.location_id,
                common_fields.location_name,
                {
                    id: 'spec',
                    label: 'Cloud Provider',
                    type: 'select',
                    values: {
                        'jclouds:aws-ec2': 'Amazon',
                        'jclouds:google-compute-engine': 'Google',
                        'jclouds:openstack': 'Openstack',
                        'jclouds:softlayer': 'Softlayer',
                        other: 'Other (supply location spec string)'
                    }
                },
                {
                    id: 'region',
                    label: 'Cloud Region',
                    type: 'text',
                    help: 'Public cloud providers often have multiple regions available. Enter the region to use if applicable (optional)',
                    disable: {
                        spec: [
                            'jclouds:openstack'
                        ]
                    }
                },
                {
                    id: 'endpoint',
                    label: 'Cloud Endpoint',
                    type: 'text',
                    help: 'If using a private cloud, the URL to connect to it is required',
                    require: {
                        spec: [
                            'jclouds:openstack'
                        ]
                    },
                    disable: {
                        spec: [
                            'jclouds:aws-ec2', 'jclouds:softlayer'
                        ]
                    }
                },
                {
                    id: 'identity',
                    label: 'Cloud Identity',
                    type: 'text',
                    help: 'The account name or access key to log in to this cloud',
                    require: true
                },
                {
                    id: 'credential',
                    label: 'Cloud Credential',
                    help: 'The password or secret key for the Cloud Identity to log in to this cloud',
                    type: 'text',
                    require: true
                }
            ],
            byon: [
                common_fields.location_id,
                common_fields.location_name,
                {
                    id: 'user',
                    label: 'User',
                    type: 'text',
                    help: 'The user to use to connect to the machines. One of the following two fields must also be supplied to connect'
                },
                {
                    id: 'password',
                    label: 'Password',
                    type: 'password',
                    help: 'The password to use to connect to the machines (if using password access)'
                },
                {
                    id: 'privateKeyFile',
                    label: 'Private Key Data',
                    type: 'textarea',
                    help: 'The contents of the private key file to use to connect to the machines (if using key access, where the corresponding public key is in the <code>.authorized_keys</code> file on the servers)'
                },
                {
                    id: 'privateKeyPassphrase',
                    label: 'Private Key Passphrase',
                    type: 'text',
                    help: 'The passphrase to unlock the private key specified above (if applicable)'
                },
                {
                    id: 'hosts',
                    label: 'Hosts',
                    type: 'textarea',
                    help: 'The IP addresses of the machines to include in this location definition, one per line',
                    list: true,
                    require: true
                }
            ],
            advanced: [
                common_fields.location_id,
                common_fields.location_name,
                {
                    id: 'spec',
                    label: 'Parent Location',
                    type: 'text',
                    help: 'The identity or spec of the location which this location should extend',
                    require: true
                }
            ]
        },
        wizard: null,

        initialize: function() {
            this.wizard = this.options.wizard;

            if (this.wizard.type === 'byon') {
                this.wizard.location.set('spec', this.wizard.type);
            }
        },

        render: function() {
            this.$el.html(this.template());

            this.wizard.enableNextAction(false);

            var that = this;
            var fields = this.fields[this.wizard.type];
            _.each(fields, function(field, index) {
                that.$('.tab-content').append(that.generateField(field));
            });

            // Force the onChange event to run
            this.$('input,textarea').blur();
            this.$('select').change();

            return this;
        },

        generateField: function(field) {
            var $input = $('<input>').attr('type', field.type);
            if (field.type === 'textarea') {
                $input = $('<textarea>');
            } else if (field.type === 'select') {
                $input = $('<select>');
                _.each(field.values, function(value, key) {
                    $input.append($('<option>').attr('value', key).html(value));
                });
                $('<input>').attr('name', field.id + '-other').insertAfter($input);
            }

            var value = '';
            if (_.contains(['name', 'spec'], field.id)) {
                value = this.wizard.location.get(field.id);
            } else {
                value = this.wizard.location.get('config')[field.id];
            }

            var $div =  $('<div>').addClass('control-group')
                .append($('<label>')
                    .addClass('control-label deploy-label')
                    .attr('for', field.id)
                    .html(field.label))
                .append($input
                    .val(value)
                    .data('list', _.isBoolean(field.list) ? field.list : false)
                    .data('require', _.isBoolean(field.require) ? field.require : false)
                    .data('require-deps', _.isObject(field.require) ? field.require : undefined)
                    .data('disable-deps', _.isObject(field.disable) ? field.disable : undefined)
                    .attr({
                        id: field.id,
                        name: field.id
                    }));

            if (field.type === 'select' && _.has(field.values, 'other')) {
                $div.append($('<input>')
                    .attr('name', field.id + '-other')
                    .addClass('location-other')
                    .hide());
            }

            if (_.has(field, 'help')) {
                $div.append($('<p>').addClass('help-block').html($('<small>').html(field.help)));
            }

            if (field.type === 'text' && field.id === 'spec') {
                var locations = new Location.Collection;
                locations.fetch({
                    success: function (model) {
                        $input.easyAutocomplete({
                            list: {
                                match: {
                                    enabled: true
                                }
                            },
                            categories: [
                                {
                                    listLocation: 'catalog',
                                    header: 'Catalog Locations'
                                },
                                {
                                    listLocation: 'spec',
                                    header: 'Spec'
                                }
                            ],
                            data: {
                                catalog: _.map(model.models, function(item) {
                                    return item.getIdentifierName();
                                }),
                                spec: ['localhost']
                            },
                            loggerEnabled: false
                        });
                    }
                });
            }

            return $div;
        },

        onChange: function(event) {
            var that = this;
            var enable = true;
            var $elm = this.$(event.currentTarget);

            if ($elm.attr('name') === 'spec') {
                if ($elm.val() === 'other') {
                    this.$('input[name=spec-other]').show();
                } else {
                    this.$('input[name=spec-other]').hide();
                }
            }

            // Update the location object based on the field values
            if ($elm.val() !== '') {
                if (_.contains(['name', 'spec'], $elm.attr('name'))) {
                    this.wizard.location.set($elm.attr('name'), $elm.val());
                } else if ($elm.attr('name') === 'spec-other') {
                    this.wizard.location.set('spec', $elm.val());
                } else {
                    var config = {};
                    config[$elm.attr('name')] = $elm.data('list') ? $elm.val().split("\n") : $elm.val();
                    this.wizard.location.set('config', _.extend(this.wizard.location.get('config'), config));
                }
            }

            this.$('input, select, textarea').each(function() {
                // Update the data-require attribute
                if (_.isObject($(this).data('require-deps'))) {
                    var require = true;
                    _.each($(this).data('require-deps'), function(values, key) {
                        require = require && _.contains(values, that.$('[name=' + key + ']').val());
                    });
                    $(this).data('require', require);
                }

                // Enable / disable field
                if (_.isObject($(this).data('disable-deps'))) {
                    var disable = true;
                    _.each($(this).data('disable-deps'), function(values, key) {
                        disable = disable && _.contains(values, that.$('[name=' + key + ']').val());
                    });
                    if (disable) {
                        $(this).attr('disabled', 'disabled').val('');
                    } else {
                        $(this).removeAttr('disabled');
                    }
                }


                // Enable / disable next button based on the require attribute
                if ($(this).data('require')) {
                    enable = enable && $(this).val() !== '';
                }
                that.wizard.enableNextAction(enable);
            });
        }
    });

    var LocationProvisioning = Backbone.View.extend({
        className: 'location-wizard-body',
        template: _.template(LocationProvisioningHtml),
        events: {
            'click .remove-entry': 'removeEntry',
            'click .add-entry': 'addEntry'
        },
        wizard: null,

        vmOptions: [
            'minCore',
            'minRam',
            'osFamily',
            'osVersionRegex',
            'os64Bit',
            'imageId',
            'imageNameRegex',
            'hardwareId',
            'inboundPorts',
            'securityGroups',
            'domainName',
            'userMetadata',
            'machineCreateAttempts',
            'destroyOnFailure'
        ],
        osOptions: [
            'user',
            'password',
            'loginUser',
            'privateKeyFile',
            'privateKeyPassphrase',
            'publicKeyFile',
            'openIptables',
            'installDevUrandom',
            'useJcloudsSshInit'

        ],
        templateOptions: [
            'subnetId',
            'mapNewVolumeToDeviceName',
            'securityGroupIds'
        ],

        initialize: function() {
            this.wizard = this.options.wizard;
        },

        render: function() {
            this.$el.html(this.template());
            this.wizard.enableNextAction(true);
            return this;
        },

        setProvisioningProperties: function() {
            var config = {};
            this.$('.control-group').each(function() {
                if ($(this).find('input.entry-key').val() !== '' && $(this).find('input.entry-value').val() !== '') {
                    config[$(this).find('input.entry-key').val()] = $(this).find('input.entry-value').val();
                }
            });
            this.wizard.location.set('config', _.extend(this.wizard.location.get('config'), config));
        },

        addEntry:function (event) {
            var that = this;
            var $entry = $(_.template(LocationProvisioningEntry, {}));
            $(event.currentTarget).prev().append($entry);

            setTimeout(function() {
                $entry.find('input.entry-key').easyAutocomplete({
                    list: {
                        match: {
                            enabled: true
                        }
                    },
                    categories: [
                        {
                            listLocation: 'vmOptions',
                            header: 'VM Creation'
                        },
                        {
                            listLocation: 'osOptions',
                            header: 'OS Setup'
                        },
                        {
                            listLocation: 'templateOptions',
                            header: 'Template Options'
                        }
                    ],
                    data: {
                        vmOptions: that.vmOptions,
                        osOptions: that.osOptions,
                        templateOptions: that.templateOptions
                    },
                    loggerEnabled: false
                });
            }, 100);
        },

        removeEntry:function (event) {
            $(event.currentTarget).parent().remove();
        }
    });

    return Wizard;
});