#!/usr/bin/env python3
"""
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 3 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, see <http://www.gnu.org/licenses/>.

Dieses Programm ist Freie Software: Sie können es unter den Bedingungen
der GNU General Public License, wie von der Free Software Foundation,
Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
veröffentlichten Version, weiterverbreiten und/oder modifizieren.

Dieses Programm wird in der Hoffnung, dass es nützlich sein wird, aber
OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
Siehe die GNU General Public License für weitere Details.

Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
Programm erhalten haben. Wenn nicht, siehe <http://www.gnu.org/licenses/>.

"""

import argparse
import os
import re
import subprocess
from os.path import expanduser
import pprint

from pubs.config import load_conf
from pubs.repo import Repository
from pubs import endecoder


class Document(object):

    """A class describing a document in the pubs library.

    It is used to upload the file to the DPT-RP1, as well as for downloading
    notes and annotations to the original file.

    Arguments
    ----------
    key : TODO
    repo : TODO

    """

    def __init__(self, key, repo, lib_name):
        self._key = key
        self._repo = repo
        self._dpt_dir: str  # Remote directory
        self._bib = repo.databroker.pull_bibentry(self._key)
        self._lib_name = lib_name

    def send_mail(self):
        """Send the reference per E-mail"""
        repo = self._repo
        key = self._key
        local_path = expanduser(repo.pull_docpath(key))

        bib_file = repo.databroker.pull_bibentry(key)
        #  content = pprint.pformat(bib_file[key])

        exporter = endecoder.EnDecoder()
        content = exporter.encode_bibdata(bib_file, [])

        # List of reserved characters in RFC 2396
        reserved = {
                " ": "%20",
                "&": "%26",
                ";": "%3B",
                "@": "%40",
                "/": "%2F",
                "?": "%3F",
                ":": "%3A",
                "=": "%3D",
                "+": "%2B",
                "$": "%24",
                ",": "%2C",
                }

        for k, v in reserved.items():
            content = content.replace(k, v)

        subprocess.run(
            [
                "evolution",
                (
                    f"mailto:?subject=Reference for {key}&body="
                    + content
                    + "&attach="
                    + local_path
                ),
                "--name='Send Pubs reference'",
            ]
        )


def do_send_mail(args):
    """TODO: Docstring for do_send_mail.
    """
    library = args.library
    citekey = args.citekey

    m = re.search("(?<=/)([a-zA-Z0-9_-]+)\.[a-z]+$", library)
    lib_name = m.group(1)

    conf = load_conf(library)
    repo = Repository(conf)

    # Create document
    doc = Document(key=citekey, repo=repo, lib_name=lib_name)
    doc.send_mail()


if __name__ == "__main__":

    pars = argparse.ArgumentParser(
        description="Send and receive pubs documents to and from a DPT-RP1"
    )

    # General options for the script
    pars.add_argument(
        "--library", help="Pubs configuration file", action="store", required=True
    )

    subparser = pars.add_subparsers(help="Commands:")

    # Parser for the 'mail' option
    cmd_mail = subparser.add_parser(
        "mail", help="Send publication associated to citekey per E-mail"
    )
    cmd_mail.add_argument(
        "citekey", type=str, nargs="?", help="Citekey in the pubs library"
    )
    cmd_mail.set_defaults(func=do_send_mail)

    # Call the selected function
    arguments = pars.parse_args()
    arguments.func(arguments)
