/*
 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.
*/

var dataimport_timeout = 2000;

solrAdminApp.controller('DataImportController',
    function($scope, $rootScope, $routeParams, $location, $timeout, $interval, $cookies, Mbeans, DataImport, Constants) {
        $scope.resetMenu("dataimport", Constants.IS_COLLECTION_PAGE);

        $scope.refresh = function () {
            Mbeans.info({core: $routeParams.core, cat: 'QUERYHANDLER'}, function (data) {
                var mbeans = data['solr-mbeans'][1];
                $scope.handlers = [];
                for (var key in mbeans) {
                    if (mbeans[key]['class'] !== key && mbeans[key]['class'] === 'org.apache.solr.handler.dataimport.DataImportHandler') {
                        $scope.handlers.push(key);
                    }
                }
                $scope.hasHandlers = $scope.handlers.length > 0;

                if (!$routeParams.handler) {
                    $location.path("/" + $routeParams.core + "/dataimport/" + $scope.handlers[0]);
                } else {
                    $scope.currentHandler = $routeParams.handler;
                }
            });

            $scope.handler = $routeParams.handler;
            if ($scope.handler && $scope.handler[0]=="/") {
                $scope.handler = $scope.handler.substr(1);
            }
            if ($scope.handler) {
                DataImport.config({core: $routeParams.core, name: $scope.handler}, function (data) {
                    try {
                        $scope.config = data.config;
                        var xml = $.parseXML(data.config);
                        $scope.entities = [];
                        $('document > entity', xml).each(function (i, element) {
                            $scope.entities.push($(element).attr('name'));
                        });
                        $scope.refreshStatus();
                    } catch (err) {
                        console.log(err);
                    }
                });
            }
            $scope.lastUpdate = "unknown";
            $scope.lastUpdateUTC = "";
        };

        $scope.toggleDebug = function () {
            $scope.isDebugMode = !$scope.isDebugMode;
            if ($scope.isDebugMode) {
                // also enable Debug checkbox
                $scope.form.showDebug = true;
            }
            $scope.showConfiguration = true;
        }

        $scope.toggleConfiguration = function () {
            $scope.showConfiguration = !$scope.showConfiguration;
        }

        $scope.toggleRawStatus = function () {
            $scope.showRawStatus = !$scope.showRawStatus;
        }

        $scope.toggleRawDebug = function () {
            $scope.showRawDebug = !$scope.showRawDebug;
        }

        $scope.reload = function () {
            DataImport.reload({core: $routeParams.core, name: $scope.handler}, function () {
                $scope.reloaded = true;
                $timeout(function () {
                    $scope.reloaded = false;
                }, 5000);
                $scope.refresh();
            });
        }

        $scope.form = {
            command: "full-import",
            verbose: false,
            clean: true,
            commit: true,
            optimize: false,
            showDebug: false,
            custom: "",
            core: $routeParams.core
        };

        $scope.submit = function () {
            var params = {};
            for (var key in $scope.form) {
                if (key == "showDebug") {
                    if ($scope.form.showDebug) {
                        params["debug"] = true;
                    }
                } else {
                    params[key] = $scope.form[key];
                }
            }
            if (params.custom.length) {
                var customParams = $scope.form.custom.split("&");
                for (var i in customParams) {
                    var parts = customParams[i].split("=");
                    params[parts[0]] = parts[1];
                }
            }
            delete params.custom;

            if ($scope.isDebugMode) {
                params.dataConfig = $scope.config;
            }

            params.core = $routeParams.core;
            params.name = $scope.handler;

            DataImport.post(params, function (data) {
                $scope.rawResponse = JSON.stringify(data, null, 2);
                $scope.refreshStatus();
            });
        };

        $scope.abort = function () {
            $scope.isAborting = true;
            DataImport.abort({core: $routeParams.core, name: $scope.handler}, function () {
                $timeout(function () {
                    $scope.isAborting = false;
                    $scope.refreshStatus();
                }, 4000);
            });
        }

        $scope.refreshStatus = function () {

            console.log("Refresh Status");

            $scope.isStatusLoading = true;
            DataImport.status({core: $routeParams.core, name: $scope.handler}, function (data) {
                if (data[0] == "<") {
                    $scope.hasHandlers = false;
                    return;
                }

                var now = new Date();
                $scope.lastUpdate = now.toTimeString().split(' ').shift();
                $scope.lastUpdateUTC = now.toUTCString();
                var messages = data.statusMessages;
                var messagesCount = 0;
                for( var key in messages ) { messagesCount++; }

                if (data.status == 'busy') {
                    $scope.status = "indexing";

                    $scope.timeElapsed = data.statusMessages['Time Elapsed'];
                    $scope.elapsedSeconds = parseSeconds($scope.timeElapsed);

                    var info = $scope.timeElapsed ? 'Indexing since ' + $scope.timeElapsed : 'Indexing ...';
                    $scope.info = showInfo(messages, true, info, $scope.elapsedSeconds);

                } else if (messages.RolledBack) {
                    $scope.status = "failure";
                    $scope.info = showInfo(messages, true);
                } else if (messages.Aborted) {
                    $scope.status = "aborted";
                    $scope.info = showInfo(messages, true, 'Aborting current Import ...');
                } else if (data.status == "idle" && messagesCount != 0) {
                    $scope.status = "success";
                    $scope.info = showInfo(messages, true);
                } else {
                    $scope.status = "idle";
                    $scope.info = showInfo(messages, false, 'No information available (idle)');
                }

                delete data.$promise;
                delete data.$resolved;

                $scope.rawStatus = JSON.stringify(data, null, 2);

                $scope.isStatusLoading = false;
                $scope.statusUpdated = true;
                $timeout(function () {
                    $scope.statusUpdated = false;
                }, dataimport_timeout / 2);
            });
        };

        $scope.updateAutoRefresh = function () {
            $scope.autorefresh = !$scope.autorefresh;
            $cookies.dataimport_autorefresh = $scope.autorefresh ? true : null;
            if ($scope.autorefresh) {
                $scope.refreshTimeout = $interval($scope.refreshStatus, dataimport_timeout);
                var onRouteChangeOff = $scope.$on('$routeChangeStart', function() {
                    $interval.cancel($scope.refreshTimeout);
                    onRouteChangeOff();
                });

            } else if ($scope.refreshTimeout) {
                $interval.cancel($scope.refreshTimeout);
            }
            $scope.refreshStatus();
        };

        $scope.refresh();

});

var showInfo = function (messages, showFull, info_text, elapsed_seconds) {

    var info = {};
    if (info_text) {
        info.text = info_text;
    } else {
        info.text = messages[''] || '';
        // format numbers included in status nicely
        /* @todo this pretty printing is hard to work out how to do in an Angularesque way:
        info.text = info.text.replace(/\d{4,}/g,
            function (match, position, string) {
                return app.format_number(parseInt(match, 10));
            }
        );
        */

        var time_taken_text = messages['Time taken'];
        info.timeTaken = parseSeconds(time_taken_text);
    }
    info.showDetails = false;

    if (showFull) {
        if (!elapsed_seconds) {
            var time_taken_text = messages['Time taken'];
            elapsed_seconds = parseSeconds(time_taken_text);
        }

        info.showDetails = true;

        var document_config = {
            'Requests': 'Total Requests made to DataSource',
            'Fetched': 'Total Rows Fetched',
            'Skipped': 'Total Documents Skipped',
            'Processed': 'Total Documents Processed'
        };

        info.docs = [];
        for (var key in document_config) {
            var value = parseInt(messages[document_config[key]], 10);
            var doc = {desc: document_config[key], name: key, value: value};
            if (elapsed_seconds && key != 'Skipped') {
                doc.speed = Math.round(value / elapsed_seconds);
            }
            info.docs.push(doc);
        }

        var dates_config = {
            'Started': 'Full Dump Started',
            'Aborted': 'Aborted',
            'Rolledback': 'Rolledback'
        };

        info.dates = [];
        for (var key in dates_config) {
            var value = messages[dates_config[key]];
            if (value) {
                value = value.replace(" ", "T")+".000Z";
                console.log(value);
                var date = {desc: dates_config[key], name: key, value: value};
                info.dates.push(date);
            }
        }
    }
    return info;
}

var parseSeconds = function(time) {
    var seconds = 0;
    var arr = new String(time || '').split('.');
    var parts = arr[0].split(':').reverse();

    for (var i = 0; i < parts.length; i++) {
        seconds += ( parseInt(parts[i], 10) || 0 ) * Math.pow(60, i);
    }

    if (arr[1] && 5 <= parseInt(arr[1][0], 10)) {
        seconds++; // treat more or equal than .5 as additional second
    }
    return seconds;
}
