// 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.

'use strict';

module.exports = (function () {
    var fs = require('fs');
    var path = require('path');

    function stripFrontMatter (text) {
        // get and replace front matter if it's there
        // NOTE:
        //      String.replace() replaces only the first occurrence
        //      of a string, which is what we want
        var rawFrontMatterString = getRawFrontMatterString(text);
        if (rawFrontMatterString !== null) {
            return text.replace(rawFrontMatterString, '');
        }

        return text;
    }

    function getFrontMatterString (text) {
        var rawFrontMatterString = getRawFrontMatterString(text);
        if (rawFrontMatterString !== null) {
            // strip out front matter markers
            var frontMatterString = rawFrontMatterString.replace(/^---\s*$/gm, '');
            return frontMatterString;
        }

        return null;
    }

    function setFrontMatterString (text, frontMatterString) {
        var textOnly = stripFrontMatter(text);
        var newText = '---\n' + frontMatterString + '---\n\n' + textOnly;
        return newText;
    }

    function getRawFrontMatterString (text) {
        // NOTE:
        //      [\s\S]  matches all characters
        //      *?      non-greedy *-match
        var match = text.match(/^(---\s*\r?\n[\s\S]*?\r?\n---\s*\r?\n)[\s\S]*$/);
        if (match === null) {
            return null;
        }
        return match[1];
    }

    function listdirsSync (root) {
        return fs.readdirSync(root).filter(function (fileName) {
            return fs.statSync(path.join(root, fileName)).isDirectory();
        });
    }

    function tocfileName (language, version, suffix) {
        var versionSlug = version.replace(/\./g, '-');
        if (suffix) {
            suffix = '-' + suffix;
        } else {
            suffix = '';
        }
        return language + '_' + versionSlug + suffix + '.yml';
    }

    function srcTocfileName (language, version) {
        return tocfileName(language, version, 'src');
    }

    function genTocfileName (language, version) {
        return tocfileName(language, version, 'gen');
    }

    function mergeObjects (a, b) {
        var c = {};

        // NOTE: b's properties override a's properties
        Object.keys(a).forEach(function (key) {
            c[key] = a[key];
        });
        Object.keys(b).forEach(function (key) {
            c[key] = b[key];
        });
        return c;
    }

    function generatedBy (scriptName) {
        return '# WARNING: This file is generated by ' + path.basename(scriptName);
    }

    return {
        stripFrontMatter: stripFrontMatter,
        getFrontMatterString: getFrontMatterString,
        setFrontMatterString: setFrontMatterString,
        getRawFrontMatterString: getRawFrontMatterString,
        listdirsSync: listdirsSync,
        tocfileName: tocfileName,
        srcTocfileName: srcTocfileName,
        genTocfileName: genTocfileName,
        mergeObjects: mergeObjects,
        generatedBy: generatedBy
    };
})();
