import json
import re

from cumulusci.core.utils import process_bool_arg
from cumulusci.core.utils import parse_datetime
from cumulusci.tasks.github.base import BaseGithubTask


class ReleaseReport(BaseGithubTask):
    task_options = {
        'date_start': {
            'description': 'Filter out releases created before this date (YYYY-MM-DD)',
        },
        'date_end': {
            'description': 'Filter out releases created after this date (YYYY-MM-DD)',
        },
        'include_beta': {
            'description': 'Include beta releases in report [default=False]',
        },
        'print': {
            'description': 'Print info to screen as JSON [default=False]',
        },
    }
    DATE_FORMAT = '%Y-%m-%d'

    def _init_options(self, kwargs):
        super(ReleaseReport, self)._init_options(kwargs)
        self.options['date_start'] = parse_datetime(
            self.options['date_start'],
            self.DATE_FORMAT,
        ) if 'date_start' in self.options else None
        self.options['date_end'] = parse_datetime(
            self.options['date_end'],
            self.DATE_FORMAT,
        ) if 'date_end' in self.options else None
        self.options['include_beta'] = process_bool_arg(
            self.options.get('include_beta', False))
        self.options['print'] = process_bool_arg(
            self.options.get('print', False))

    def _run_task(self):
        releases = []
        last_time = None
        repo = self.get_repo()
        regex_compiled_prefix = re.compile(
            r'^((?P<sandbox>{})|(?P<production>{}))(?P<remaining>.*)$'.format(
                self.project_config.project__git__push_prefix_sandbox,
                self.project_config.project__git__push_prefix_production,
            ))
        regex_compiled_date = re.compile(r'\s*(?P<date>\d\d\d\d-\d\d-\d\d)')
        for release in repo.iter_releases():
            if release.prerelease and not self.options['include_beta']:
                continue
            if self.options['date_start'] and release.created_at < self.options[
                    'date_start']:
                continue
            if self.options[
                    'date_end'] and release.created_at > self.options['date_end']:
                continue
            release_info = {
                'url': release.html_url,
                'name': release.name,
                'tag': release.tag_name,
                'beta': release.prerelease,
                'time_created': release.created_at,
                'time_push_sandbox': None,
                'time_push_production': None,
            }
            for line in release.body.splitlines():
                m = regex_compiled_prefix.match(line)
                if m:
                    if not m.group('remaining'):
                        self.logger.warning(
                            '[%s] Nothing found after push date prefix: %s',
                            release_info['url'],
                            line,
                        )
                        continue
                    m2 = regex_compiled_date.match(m.group('remaining'))
                    if not m2:
                        self.logger.warning(
                            (
                                '[%s] Could not find date in line: %s\n'
                                'Use the format YYYY-MM-DD'
                            ),
                            release_info['url'],
                            line,
                        )
                        continue
                    if m.group('sandbox'):
                        key = 'time_push_sandbox'
                    else:
                        key = 'time_push_production'
                    release_info[key] = parse_datetime(
                        m2.group('date'),
                        self.DATE_FORMAT,
                    )
            releases.append(release_info)
        self.return_values = {'releases': releases}
        if self.options['print']:
            print(json.dumps(releases, indent=4, sort_keys=True, default=str))
