// 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 path = require('path');
var yaml = require('js-yaml');

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

// constants
var USAGE = 'Usage: gen_defaults.js [docsRoot] [latestVersion]';
var DEV_VERSION_NAME = 'dev';

// constants for sitemap.xml
// reference:
//      http://www.sitemaps.org/protocol.html#xmlTagDefinitions
var LATEST_CHANGE_FREQUENCY = 'monthly';
var LATEST_PAGE_PRIORITY = 0.8;

var DEFAULT_CHANGE_FREQUENCY = 'monthly';
var DEFAULT_PAGE_PRIORITY = LATEST_PAGE_PRIORITY / 2;

var DEV_CHANGE_FREQUENCY = 'daily';
var DEV_PAGE_PRIORITY = LATEST_PAGE_PRIORITY / 4;

function main () {

    var rootDir = process.argv[2];
    var latestVersionName = process.argv[3];

    if (!rootDir) {
        console.error(USAGE);
        console.error('Please specify the docs root directory from which to generate defaults.');
        process.exit(1);
    }

    if (!latestVersionName) {
        console.error(USAGE);
        console.error('Please specify the latest version of the docs.');
        process.exit(1);
    }

    // create defaults config
    var config = { 'defaults': [] };

    // set defaults for each language
    util.listdirsSync(rootDir).forEach(function (langName) {

        var langPath = path.join(rootDir, langName);
        var languageDefaults = {
            scope: {
                path: 'docs/' + langName
            },
            values: {
                language: langName,
                layout: 'docs-' + langName
            }
        };

        config.defaults.push(languageDefaults);

        // set defaults for each version
        util.listdirsSync(langPath).forEach(function (versionName) {

            var tocfile = util.genTocfileName(langName, versionName);

            var changeFrequency = DEFAULT_CHANGE_FREQUENCY;
            var pagePriority = DEFAULT_PAGE_PRIORITY;

            // adjust priority and frequency based on version
            if (versionName === latestVersionName) {
                changeFrequency = LATEST_CHANGE_FREQUENCY;
                pagePriority = LATEST_PAGE_PRIORITY;
            } else if (versionName === DEV_VERSION_NAME) {
                changeFrequency = DEV_CHANGE_FREQUENCY;
                pagePriority = DEV_PAGE_PRIORITY;
            }

            var current = false;
            if (versionName === latestVersionName || versionName === DEV_VERSION_NAME) {
                current = true;
            }

            var versionDefaults = {
                scope: {
                    path: 'docs/' + langName + '/' + versionName
                },
                values: {
                    version: versionName,
                    tocfile: tocfile.replace('.yml', ''),
                    change_frequency: changeFrequency,
                    priority: pagePriority,
                    current: current
                }
            };

            config.defaults.push(versionDefaults);
        });
    });

    console.log(util.generatedBy(__filename));
    console.log(yaml.dump(config, { indent: 4 }));
}

main();
