# Copyright (C) 2015-2020  The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information

from typing import Any, Dict, List, Optional, Union

from email import utils

from swh.model.model import (
    Person, Revision, RevisionType, TimestampWithTimezone
)
from swh.loader.package.utils import EMPTY_AUTHOR

from .utils import strdate_to_timestamp


def svn_date_to_swh_date(
        strdate: Optional[str]) -> TimestampWithTimezone:
    """Convert a string date to an swh one.

    Args:
        strdate: A string formatted for .utils.strdate_to_timestamp
        to do its jobs

    Returns:
        An swh date format

    """
    return TimestampWithTimezone(
        timestamp=strdate_to_timestamp(strdate),
        offset=0,
        negative_utc=False,
    )


def svn_author_to_swh_person(author: Union[str, bytes]) -> Person:
    """Convert an svn author to an swh person.
    Default policy: No information is added.

    Args:
        author (string): the svn author (in bytes)

    Returns:
        a Person

    """
    # TODO: Align this function and move it up as library helper function
    if not author:
        return EMPTY_AUTHOR

    if isinstance(author, str):
        author = author.encode('utf-8')

    if b'<' in author and b'>' in author:
        name, email = utils.parseaddr(author.decode('utf-8'))
        return Person(
            fullname=author,
            name=name.encode('utf-8'),
            email=email.encode('utf-8')
        )

    return Person(fullname=author, name=author, email=None)


def build_swh_revision(
        rev: int, commit: Dict, repo_uuid: str, dir_id: bytes,
        parents: List[bytes]) -> Revision:
    """Given a svn revision, build a swh revision.

    This adds an ['metadata']['extra-headers'] entry with the
    repository's uuid and the svn revision.

    Args:
        - rev: the svn revision number
        - commit: the commit metadata
        - repo_uuid: The repository's uuid
        - dir_id: the tree's hash identifier
        - parents: the revision's parents identifier

    Returns:
        The swh revision dictionary.

    """
    author = commit['author_name']
    msg = commit['message']
    date = commit['author_date']

    metadata: Dict[str, Any] = {
        'extra_headers': [
            ['svn_repo_uuid', repo_uuid],
            ['svn_revision', str(rev).encode('utf-8')]
        ]
    }

    return Revision(
        type=RevisionType.SUBVERSION,
        date=date,
        committer_date=date,
        directory=dir_id,
        message=msg,
        author=author,
        committer=author,
        synthetic=True,
        metadata=metadata,
        parents=parents,
    )
