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


// Prepare release materials like mail, release note

const commander = require('commander');
const fse = require('fs-extra');
const pathTool = require('path');
const https = require('https');

commander
    .usage('[options]')
    .description([
        'Generate source release'
    ].join('\n'))
    .option(
        '--rcversion <version>',
        'Release version'
    )
    .option(
        '--commit <commit>',
        'Hash of commit'
    )
    .option(
        '--repo <repo>',
        'Repo'
    )
    .option(
        '--out <out>',
        'Out directory. Default to be tmp/release-mail'
    )
    .parse(process.argv);

const outDir = pathTool.resolve(process.cwd(), commander.out || 'tmp/release-materials');
const releaseCommit = commander.commit;
if (!releaseCommit) {
    throw new Error('Release commit is required');
}
const repo = commander.repo || 'apache/echarts';

let rcVersion = commander.rcversion + '';
if (rcVersion.startsWith('v')) {   // tag may have v prefix, v5.1.0
    rcVersion = rcVersion.substr(1);
}
if (rcVersion.indexOf('-rc.') < 0) {
    throw new Error('Only rc version is accepeted.');
}

const parts = /(\d+)\.(\d+)\.(\d+)\-rc\.(\d+)/.exec(rcVersion);
if (!parts) {
    throw new Error(`Invalid version number ${rcVersion}`);
}

const major = +parts[1];
const minor = +parts[2];
const patch = +parts[3];
const rc = +parts[4];

const stableVersion = `${major}.${minor}.${patch}`;
const releaseFullName = `Apache ECharts ${stableVersion} (release candidate ${rc})`;

console.log('[Release Repo] ' + repo);
console.log('[Release Verion] ' + rcVersion);
console.log('[Release Commit] ' + releaseCommit);
console.log('[Release Name] ' + releaseFullName);

const voteTpl = fse.readFileSync(pathTool.join(__dirname, './template/vote-release.tpl'), 'utf-8');
const announceTpl = fse.readFileSync(pathTool.join(__dirname, './template/announce-release.tpl'), 'utf-8');
const voteUntil = new Date(+new Date() + (72 + 12) * 3600 * 1000);   // 3.5 day.

fse.ensureDirSync(outDir);
fse.writeFileSync(
    pathTool.resolve(outDir, 'vote.txt'),
    voteTpl.replace(/{{ECHARTS_RELEASE_VERSION}}/g, rcVersion)
        .replace(/{{ECHARTS_RELEASE_VERSION_FULL_NAME}}/g, releaseFullName)
        .replace(/{{ECHARTS_RELEASE_COMMIT}}/g, releaseCommit)
        .replace(/{{VOTE_UNTIL}}/g, voteUntil.toISOString()),
    'utf-8'
);

fse.writeFileSync(
    pathTool.resolve(outDir, 'announce.txt'),
    announceTpl.replace(/{{ECHARTS_RELEASE_VERSION}}/g, stableVersion)
        .replace(/{{ECHARTS_RELEASE_COMMIT}}/g, releaseCommit),
    'utf-8'
);


// Fetch RELEASE_NOTE
https.get({
    hostname: 'api.github.com',
    path: `/repos/${repo}/releases`,
    headers: {
        'User-Agent': 'NodeJS'
    }
}, function (res) {
    console.log(`https://api.github.com/repos/${repo}/releases`);
    if (res.statusCode !== 200) {
        console.error(`Failed to fetch releases ${res.statusCode}`);
        res.resume();
        return;
    }

    res.setEncoding('utf8');
    let rawData = '';
    res.on('data', (chunk) => {
        rawData += chunk;
    });
    res.on('end', () => {
        let releaseNote = '';

        const releases = JSON.parse(rawData);
        const found = releases.find(release => release.name === rcVersion);
        if (!found) {
            throw 'Can\'t found release';
        }
        else {
            releaseNote = found.body.trim();
            if (!releaseNote) {
                throw 'Release description is empty';
            }
        }

        const firstLine = releaseNote.split('\n')[0];
        if (firstLine.indexOf(stableVersion) < 0) {
            // Add version if release note is not start with version.
        }
        releaseNote = `## ${stableVersion}\n\n${releaseNote}`;

        fse.writeFileSync(
            pathTool.resolve(outDir, 'RELEASE_NOTE.txt'),
            releaseNote,
            'utf-8'
        );
    });
  }).on('error', (e) => {
      throw e;
  });