import zeroFill from ‘../utils/zero-fill’;

export var formattingTokens = /([[^[]*])|(\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w?|W?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g;

var localFormattingTokens = /([[^[]*])|(\)?(LTS|LT|LL?L?L?|l{1,4})/g;

var formatFunctions = {};

export var formatTokenFunctions = {};

// token: ‘M’ // padded: [‘MM’, 2] // ordinal: ‘Mo’ // callback: function () { this.month() + 1 } export function addFormatToken (token, padded, ordinal, callback) {

var func = callback;
if (typeof callback === 'string') {
    func = function () {
        return this[callback]();
    };
}
if (token) {
    formatTokenFunctions[token] = func;
}
if (padded) {
    formatTokenFunctions[padded[0]] = function () {
        return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
    };
}
if (ordinal) {
    formatTokenFunctions[ordinal] = function () {
        return this.localeData().ordinal(func.apply(this, arguments), token);
    };
}

}

function removeFormattingTokens(input) {

if (input.match(/\[[\s\S]/)) {
    return input.replace(/^\[|\]$/g, '');
}
return input.replace(/\\/g, '');

}

function makeFormatFunction(format) {

var array = format.match(formattingTokens), i, length;

for (i = 0, length = array.length; i < length; i++) {
    if (formatTokenFunctions[array[i]]) {
        array[i] = formatTokenFunctions[array[i]];
    } else {
        array[i] = removeFormattingTokens(array[i]);
    }
}

return function (mom) {
    var output = '';
    for (i = 0; i < length; i++) {
        output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
    }
    return output;
};

}

// format date using native date object export function formatMoment(m, format) {

if (!m.isValid()) {
    return m.localeData().invalidDate();
}

format = expandFormat(format, m.localeData());

if (!formatFunctions[format]) {
    formatFunctions[format] = makeFormatFunction(format);
}

return formatFunctions[format](m);

}

export function expandFormat(format, locale) {

var i = 5;

function replaceLongDateFormatTokens(input) {
    return locale.longDateFormat(input) || input;
}

localFormattingTokens.lastIndex = 0;
while (i >= 0 && localFormattingTokens.test(format)) {
    format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
    localFormattingTokens.lastIndex = 0;
    i -= 1;
}

return format;

}