#!/usr/bin/python3
#
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2018 IBM Corp.

import argparse
import sys
from collections import namedtuple, OrderedDict
from enum import Enum, unique
from typing import (Dict, NamedTuple, Iterator, Sequence, Union, Optional,
                    List, cast, IO)
from pprint import pprint

@unique
class LineType(Enum):
    REPO = 1
    MAINTAINER = 2
    REVIEWER = 3
    FORKED = 4
    COMMENT = 5

@unique
class ParseState(Enum):
    BEGIN = 1
    BLOCK = 2

Email = NamedTuple("Email", [("name", str), ("address", str)])
Identity = NamedTuple("Identity", [("email", Email), ("irc", Optional[str])])
Entry = NamedTuple("Entry", [("type", LineType), ("content", str)])

def parse_line(line: str) -> Optional[Entry]:
    sline = line.strip()
    if not sline:
        return None

    if sline == "MAINTAINERS":
        return Entry(LineType.REPO, sline)

    tag = line[:2]
    if '@' in tag:
        return Entry(LineType.REPO, sline[1:].split(":")[0].strip())
    elif tag == 'M:':
        return Entry(LineType.MAINTAINER, sline.split(":")[1].strip())
    elif tag == 'R:':
        return Entry(LineType.REVIEWER, sline.split(":")[1].strip())
    elif tag == 'F:':
        return Entry(LineType.FORKED, sline[2:].strip())
    elif '#' in tag:
        return Entry(LineType.COMMENT, line)

    return None

D = Union[str, List[Identity], List[str]]

def parse_repo(content: str) -> str:
    return content

def parse_forked(content: str) -> str:
    return content

def parse_irc(src: Iterator[str]) -> Optional[str]:
    irc = ""
    for c in src:
        if c == '#':
            return None
        if c == '<':
            break
    else:
        return None

    for c in src:
        if c in '!#':
            return irc.strip()
        irc += c

    raise ValueError("Unterminated IRC handle")

def parse_address(src: Iterator[str]) -> str:
    addr = ""
    for c in src:
        if c in '>#':
            return addr.strip()
        addr += c
    raise ValueError("Unterminated email address")

def parse_name(src: Iterator[str]) -> str:
    name = ""
    for c in src:
        if c in '<#':
            return name.strip()
        name += c
    raise ValueError("Unterminated name")

def parse_email(src: Iterator[str]) -> Email:
    name = parse_name(src)
    address = parse_address(src)
    return Email(name, address)

def parse_identity(content: str) -> Identity:
    ci = iter(content)
    email = parse_email(ci)
    irc = parse_irc(ci)
    return Identity(email, irc)

B = Dict[LineType, D]

def parse_block(src: Iterator[str]) -> Optional[B]:
    state = ParseState.BEGIN
    repo: Dict[LineType, D] = OrderedDict()
    for line in src:
        try:
            entry = parse_line(line)
            if state == ParseState.BEGIN and not entry:
                continue
            elif state == ParseState.BEGIN and entry:
                state = ParseState.BLOCK
            elif state == ParseState.BLOCK and not entry:
                return repo

            assert entry

            if entry.type == LineType.REPO:
                repo[entry.type] = parse_repo(entry.content)
            elif entry.type in { LineType.MAINTAINER, LineType.REVIEWER }:
                if not entry.type in repo:
                    repo[entry.type] = cast(List[Identity], list())
                cast(list, repo[entry.type]).append(parse_identity(entry.content))
            elif entry.type == LineType.FORKED:
                repo[entry.type] = parse_forked(entry.content)
            elif entry.type == LineType.COMMENT:
                if not entry.type in repo:
                    repo[entry.type] = cast(List[str], list())
                cast(list, repo[entry.type]).append(entry.content)
        except ValueError as e:
            print("Failed to parse line '{}': {}".format(line.strip(), e))

    if not repo:
        return None

    return repo

def trash_preamble(src: Iterator[str]) -> None:
    s = 0
    for line in src:
        sline = line.strip()
        if "START OF MAINTAINERS LIST" == sline:
            s = 1
        if s == 1 and sline == "-------------------------":
            break

def parse_maintainers(src: Iterator[str]) -> Dict[D, B]:
    maintainers: Dict[D, B] = OrderedDict()
    trash_preamble(src)
    while True:
        repo: B = parse_block(src)
        if not repo:
            break
        maintainers[repo[LineType.REPO]] = repo
    return maintainers

def assemble_name(name: str, dst: IO[str]) -> None:
    dst.write(name)

def assemble_address(address: str, dst: IO[str]) -> None:
    dst.write("<")
    dst.write(address)
    dst.write(">")

def assemble_email(email: Email, dst: IO[str]) -> None:
    assemble_name(email.name, dst)
    dst.write(" ")
    assemble_address(email.address, dst)

def assemble_irc(irc: Optional[str], dst: IO[str]) -> None:
    if irc:
        dst.write(" ")
        dst.write("<")
        dst.write(irc)
        dst.write("!>")

def assemble_identity(identity: Identity, dst: IO[str]) -> None:
    assemble_email(identity.email, dst)
    assemble_irc(identity.irc, dst)

def assemble_maintainers(identities: List[Identity], dst: IO[str]) -> None:
    for i in identities:
        dst.write("M:  ")
        assemble_identity(i, dst)
        dst.write("\n")

def assemble_reviewers(identities: List[Identity], dst: IO[str]) -> None:
    for i in identities:
        dst.write("R:  ")
        assemble_identity(i, dst)
        dst.write("\n")

def assemble_forked(content: str, dst: IO[str]) -> None:
    if content:
        dst.write("F:  ")
        dst.write(content)
        dst.write("\n")

def assemble_comment(content: List[str], dst: IO[str]) -> None:
    dst.write("".join(content))

def assemble_block(block: B, default: B, dst: IO[str]) -> None:
    if LineType.COMMENT in block:
        assemble_comment(cast(List[str], block[LineType.COMMENT]), dst)
    if LineType.MAINTAINER in block:
        maintainers = block[LineType.MAINTAINER]
    else:
        maintainers = default[LineType.MAINTAINER]
    assemble_maintainers(cast(List[Identity], maintainers), dst)
    if LineType.REVIEWER in block:
        assemble_reviewers(cast(List[Identity], block[LineType.REVIEWER]), dst)
    if LineType.FORKED in block:
        assemble_forked(cast(str, block[LineType.FORKED]), dst)

def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("maintainers", type=argparse.FileType('r'),
                        default=sys.stdin)
    parser.add_argument("output", type=argparse.FileType('w'),
                        default=sys.stdout)
    args = parser.parse_args()
    blocks = parse_maintainers(args.maintainers)
    for block in blocks.values():
        print(block[LineType.REPO])
        assemble_block(block, blocks['MAINTAINERS'], args.output)
        print()

if __name__ == "__main__":
    main()
