#!/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
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]}'
                    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))
        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)
