# Copyright (C) 2006, 2009, 2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

"""A generator which creates a yaml stanza of the current tree info"""

import yaml

from breezy import errors, hooks
from breezy.revision import NULL_REVISION
from breezy.version_info_formats import VersionInfoBuilder, create_date_str


class YamlVersionInfoBuilder(VersionInfoBuilder):
    """This writes a yaml stream out."""

    def generate(self, to_file):
        info = {}
        revision_id = self._get_revision_id()
        if revision_id != NULL_REVISION:
            info['revision-id'] = revision_id.decode('utf-8')
            rev = self._branch.repository.get_revision(revision_id)
            info['date'] = create_date_str(rev.timestamp, rev.timezone)
            try:
                revno = self._get_revno_str(revision_id)
            except errors.GhostRevisionsHaveNoRevno:
                revno = None
            for hook in YamlVersionInfoBuilder.hooks['revision']:
                hook(rev, info)
        else:
            revno = '0'

        info['build-date'] = create_date_str()
        if revno is not None:
            info['revno'] = revno

        if self._branch.nick is not None:
            info['branch-nick'] = self._branch.nick

        if self._check or self._include_file_revs:
            self._extract_file_revisions()

        if self._check:
            if self._clean:
                info['clean'] = True
            else:
                info['clean'] = False

        if self._include_history:
            log = []
            for (revision_id, message,
                 timestamp, timezone) in self._iter_revision_history():
                log.append({
                    'id': revision_id.decode('utf-8'),
                    'message': message,
                    'date': create_date_str(timestamp, timezone),
                })
            info['revisions'] = log

        if self._include_file_revs:
            files = []
            for path in sorted(self._file_revisions.keys()):
                files.append({
                    'path': path,
                    'revision': (
                        self._file_revisions[path].decode('utf-8')
                        if isinstance(self._file_revisions[path], bytes) else self._file_revisions[path])
                })
            info['file-revisions'] = files

        yaml.dump(info, to_file)


class YamlVersionInfoBuilderHooks(hooks.Hooks):
    """Hooks for yaml-formatted version-info output."""

    def __init__(self):
        super().__init__(
            "breezy.version_info_formats.format_yaml", "YamlVersionInfoBuilder.hooks")
        self.add_hook('revision',
                      "Invoked when adding information about a revision to the"
                      " YAML stanza that is printed. revision is called with a"
                      " revision object and a YAML stanza.", (3, 3))


YamlVersionInfoBuilder.hooks = YamlVersionInfoBuilderHooks()  # type: ignore
