// 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';

var fs = require('fs');
var path = require('path');
var yaml = require('js-yaml');
var glob = require('glob');
var optimist = require('optimist');

var util = require('./util');

// constants
var LATEST_ALIAS_URI = '/latest/';

// helpers
function pathToURI (filePath, rootPath) {
    return filePath
        .replace(new RegExp('^' + rootPath), '')
        .replace(new RegExp('\\.md$'), '.html');
}

function pagesFromRedirects (redirects, languages) {
    var pages = {};

    // add docs redirects
    if (typeof redirects.docs !== 'undefined') {
        for (var redirectSource in redirects.docs) {
            // add an entry for the redirect's source, once for each language
            for (var i = 0; i < languages.length; i++) {
                var language = languages[i];
                var pagePath = '/docs/' + language + '/' + redirectSource;

                pages[pagePath] = true;
            }
        }
    }

    return pages;
}

function isInLatestDocs (uri, latestVersion) {
    return uri.indexOf('/' + latestVersion + '/') !== (-1);
}

// main
function main () {
    // get args
    var argv = optimist
        .usage('Usage: $0 [options]')
        .demand('languages').describe('languages', 'comma-separated list of docs languages')
        .demand('latestVersion').describe('latestVersion', 'the current latest docs version')
        .demand('siteRoot').describe('siteRoot', 'the source ToC for the given directory')
        .string('redirectsFile').describe('redirectsFile', 'file containing redirects for the website').default('redirectsFile', null)
        .argv;

    var siteRootPath = argv.siteRoot;
    var redirectsFilePath = argv.redirectsFile;
    var latestVersion = argv.latestVersion;
    var languages = argv.languages.split(',');

    // pages to return
    var pages = {};

    // add pages for redirects if a redirects file was passed
    if (redirectsFilePath !== null) {
        var redirectsString = fs.readFileSync(redirectsFilePath);
        var redirects = yaml.load(redirectsString);
        var redirectsPages = pagesFromRedirects(redirects, languages);

        pages = redirectsPages;
    }

    // add entries for all Markdown files in the site root
    var allMarkdownFiles = path.join(siteRootPath, '**/*.md');
    glob(allMarkdownFiles, function (error, filePaths) {
        if (error) throw error;

        for (var i = 0; i < filePaths.length; i++) {
            var filePath = filePaths[i];
            var fileURI = pathToURI(filePath, siteRootPath);

            // add the page
            pages[fileURI] = true;

            // also add /latest/ version for pages in latest docs
            if (isInLatestDocs(fileURI, latestVersion)) {
                var latestURI = fileURI.replace('/' + latestVersion + '/', LATEST_ALIAS_URI);

                pages[latestURI] = true;
            }
        }

        // print output
        console.log(util.generatedBy(__filename));
        console.log(yaml.dump(pages));
    });
}

if (require.main === module) {
    main();
}
