(function () {
    'use strict';

    angular.module('uniflash').config(['$provide', function ($provide) {

        $provide.decorator('$log', ['$delegate', 'ufLogger', function ($delegate, ufLogger) {
            function supplant(str, o) {
                return str.replace(/{([^{}]*)}/g, function (a, b) {
                    let r = o[b];
                    return typeof r === 'string' || typeof r === 'number' ? r : a;
                });
            };

            function enhancedLog(funcName, origFunc) {
                return function () {
                    let date = new Date();
                    let hh = ('00' + date.getHours()).slice(-2);
                    let mm = ('00' + date.getMinutes()).slice(-2);
                    let ss = ('00' + date.getSeconds()).slice(-2);
                    let mss = ('000' + date.getMilliseconds()).slice(-3);
                    let now = hh + ':' + mm + ':' + ss + ':' + mss;

                    let args = [].slice.call(arguments);
                    if (!args[0] || args[0] === '') {
                        return;
                    }

                    args[0] = (typeof args[0] === 'string') ? args[0] : JSON.stringify(args[0]);
                    args[0] = supplant('{0} {1} - {2}', [now, funcName, args[0]]);

                    // Call the original with the output prepended with formatted timestamp
                    if (ufLogger.printToConsole) {
                        origFunc.apply(null, args);
                    }

                    ufLogger.log(args[0]);
                };
            };

            // augment $log functions
            let logFn = $delegate.log;
            $delegate.log = enhancedLog('log', logFn);

            let infoFn = $delegate.info;
            $delegate.info = enhancedLog('info', infoFn);

            let warnFn = $delegate.warn;
            $delegate.warn = enhancedLog('warn', warnFn);

            let errorFn = $delegate.error;
            $delegate.error = enhancedLog('error', errorFn);

            let debugFn = $delegate.debug;
            $delegate.debug = enhancedLog('debug', debugFn);

            return $delegate;
        }]);
    }]);
})();