/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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.
 */

/*
 ONOS GUI -- Widget -- Chart Service
 */
(function () {
    'use strict';

    // injected references
    // fs -> FnService
    // wss -> WebSocketService
    // ls -> LoadingService
    var $log, $interval, $timeout, fs, wss, ls;

    // constants
    var refreshInterval = 2000;

    // example params to buildChart:
    // {
    //    scope: $scope,     <- controller scope
    //    tag: 'device',     <- chart identifier
    //    respCb: respCb,    <- websocket response callback (optional)
    //    query: params      <- query parameters in URL (optional)
    // }
    //          Note: query is always an object (empty or containing properties)
    //                 it comes from $location.search()
    function buildChart(o) {
        var handlers = {},
            root = o.tag + 's',
            req = o.tag + 'DataRequest',
            resp = o.tag + 'DataResponse',
            onResp = fs.isF(o.respCb),
            oldChartData = [],
            refreshPromise;

        o.scope.chartData = [];
        o.scope.changedData = [];
        o.scope.reqParams = o.reqParams || {};
        o.scope.autoRefresh = true;
        o.scope.autoRefreshTip = 'Toggle auto refresh';

        // === websocket functions ===
        // response
        function respCb(data) {
            ls.stop();
            o.scope.chartData = data[root];
            onResp && onResp();

            // check if data changed
            if (!angular.equals(o.scope.chartData, oldChartData)) {
                o.scope.changedData = [];
                // only refresh the chart if there are new changes
                if (oldChartData.length) {
                    angular.forEach(o.scope.chartData, function (item) {
                        if (!fs.containsObj(oldChartData, item)) {
                            o.scope.changedData.push(item);
                        }
                    });
                }
                angular.copy(o.scope.chartData, oldChartData);
            }
            o.scope.$apply();
        }
        handlers[resp] = respCb;
        wss.bindHandlers(handlers);

        // request
        function requestCb(params) {
            var p = angular.extend({}, params, o.query);
            if (wss.isConnected()) {
                wss.sendEvent(req, p);
                ls.start();
            }
        }
        o.scope.requestCallback = requestCb;

        // === autoRefresh functions ===
        function fetchDataIfNotWaiting() {
            if (!ls.waiting()) {
                if (fs.debugOn('widget')) {
                    $log.debug('Refreshing ' + root + ' page');
                }
                requestCb(o.scope.reqParams);
            }
        }

        function startRefresh() {
            refreshPromise = $interval(fetchDataIfNotWaiting, refreshInterval);
        }

        function stopRefresh() {
            if (refreshPromise) {
                $interval.cancel(refreshPromise);
                refreshPromise = null;
            }
        }

        function toggleRefresh() {
            o.scope.autoRefresh = !o.scope.autoRefresh;
            o.scope.autoRefresh ? startRefresh() : stopRefresh();
        }
        o.scope.toggleRefresh = toggleRefresh;

        // === Cleanup on destroyed scope ===
        o.scope.$on('$destroy', function () {
            wss.unbindHandlers(handlers);
            stopRefresh();
            ls.stop();
        });

        requestCb(o.scope.reqParams);
        startRefresh();
    }

    angular.module('onosWidget')
        .factory('ChartBuilderService',
        ['$log', '$interval', '$timeout', 'FnService', 'WebSocketService',
            'LoadingService',

            function (_$log_, _$interval_, _$timeout_, _fs_, _wss_, _ls_) {
                $log = _$log_;
                $interval = _$interval_;
                $timeout = _$timeout_;
                fs = _fs_;
                wss = _wss_;
                ls = _ls_;

                return {
                    buildChart: buildChart
                };
            }]);
}());
