#!/usr/bin/env python3

# Copyright 2019 The Meson development team
#
# Licensed 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.
'''
  Generates release notes for new releases of Meson build system
'''
import argparse
import subprocess
import re
import shutil
import datetime
from pathlib import Path

RELNOTE_TEMPLATE = '''---
title: Release {}
short-description: Release notes for {}
...

# New features{}

'''


def add_to_sitemap(sitemap, output_sitemap):
    '''
       Adds release note entry to sitemap.txt.
    '''
    sitemapfile = Path(sitemap)
    with sitemapfile.open(encoding='utf-8') as s_f:
        lines = s_f.readlines()
    relnotes = None
    to_version = None
    output = Path(output_sitemap)
    output.parent.mkdir(exist_ok=True, parents=True)
    with output.open('w', encoding='utf-8') as s_f:
        for line in lines:
            if relnotes is None:
                m = re.match(r'[\s]*Release-notes-for-([0-9]+)\.([0-9]+)\.([0-9]+)\.md', line)
                if m:
                    from_version = f'{m[1]}.{m[2]}.{m[3]}'
                    if from_version == '0.64.0':
                        to_version = '1.0.0'
                    else:
                        to_version = f'{m[1]}.{int(m[2]) + 1}.{m[3]}'
                    new_line = line.replace(from_version, to_version)
                    relnotes = new_line.strip()
                    s_f.write(new_line)
            s_f.write(line)

    if sitemapfile == output:
        subprocess.check_call(['git', 'add', output])

    return relnotes, to_version

def generate(relnotes, to_version, source_dir, output_dir):
    '''
       Generate notes for Meson build next release.
    '''
    title_suffix = ' (in development)' if output_dir else ''
    title = f'{to_version}{title_suffix}'
    output = Path(output_dir, relnotes) if output_dir else Path('markdown', relnotes)
    output.parent.mkdir(exist_ok=True, parents=True)
    with output.open('w', encoding='utf-8') as ofile:
        ofile.write(RELNOTE_TEMPLATE.format(title, to_version, title_suffix))
        if not output_dir:
            date = datetime.date.today()
            date_str = date.strftime("%d %B %Y")
            ofile.write(f'Meson {to_version} was released on {date_str}\n')
        for snippetfile in sorted(Path(source_dir, 'markdown/snippets').glob('*.md')):
            snippet = snippetfile.read_text(encoding='utf-8')
            ofile.write(snippet)
            if not snippet.endswith('\n'):
                ofile.write('\n')
            ofile.write('\n')

    if not output_dir:
        subprocess.check_call(['git', 'rm', 'markdown/snippets/*.md'])
        subprocess.check_call(['git', 'add', output])

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Generate meson docs')
    parser.add_argument('--input-sitemap', default='sitemap.txt')
    parser.add_argument('--output-sitemap', default='sitemap.txt')
    parser.add_argument('--source-dir', default='.')
    parser.add_argument('--output-dir')

    args = parser.parse_args()

    if Path(args.source_dir, 'markdown/snippets').glob('*.md'):
        relnotes, to_version = add_to_sitemap(args.input_sitemap, args.output_sitemap)
        generate(relnotes, to_version, args.source_dir, args.output_dir)
    elif args.input_sitemap != args.output_sitemap:
        shutil.copyfile(args.input_sitemap, args.output_sitemap)
