#!/usr/bin/env python3
# Copyright (C) 2013 Wieland Hoffmann
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import configparser
import logging
import re
import sys
import subprocess

from os import fdopen, getenv, remove
from os.path import basename, expanduser, join
from tempfile import mkstemp


def build_keycmd_file(keycmds):
    if keycmds is None:
        return None
    (fd, filename) = mkstemp("mplayerconf")
    _file = fdopen(fd, "wt")
    for key, command in keycmds:
        logging.debug("%s: %s" % (key, command))
        if key not in ("regex", "options"):
            _file.write("%s %s\n" % (key, command))
    _file.close()
    return filename


def read_config():
    configfile = join(getenv("XDG_CONFIG_HOME", expanduser("~/.config")),
                      "mplayer-autocmd", "config")
    parser = configparser.ConfigParser()
    logging.debug("Reading %s" % configfile)
    parser.read(configfile)
    return parser


def setup_logging():
    if "-d" in sys.argv:
        logging.basicConfig(level=logging.DEBUG,
                            format="%(levelname)s: %(funcName)s: %(msg)s")
        sys.argv.remove("-d")
    else:
        logging.basicConfig(level=logging.INFO, format="%(msg)s")


def find_config_section_for_filename(options, filename):
    for section in options.sections():
        # Sanity check
        if "regex" not in options.options(section):
            raise ValueError("Section %s does not contain a 'regex' key" % section)
        logging.debug("%s - %s" % (options.get(section, "regex"), filename))
        if re.search(options.get(section, "regex"), filename, re.IGNORECASE) is not None:
            logging.info("Using profile '%s'" % section)
            return section
    return None


non_keyboard_keys = ("regex", "options", "remove_after_playing")


def main():
    if len(sys.argv) < 2:
        sys.exit(1)

    setup_logging()
    options = read_config()
    # Use the first argument to find the correct section
    filename = basename(sys.argv[1])
    match = find_config_section_for_filename(options, filename)

    args = ["mplayer"]
    keycmd_file = None
    remove_after_playing = False
    if match:
        args.extend(options.get(match, "options", fallback="").split())
        remove_after_playing = options.getboolean(match,
                                "remove_after_playing", fallback=False)
        items = options.items(match)
        for item in non_keyboard_keys:
            try:
                items.remove(item)
            except ValueError:
                pass
        keycmd_file = build_keycmd_file(items)
        input_conf_string = "--input=conf=%s" % keycmd_file

        args.extend([input_conf_string])
    else:
        logging.info("No profile found")

    args.extend(sys.argv[1:])
    logging.info("Calling %s" % args)
    ret = subprocess.call(args)
    if not ret and remove_after_playing:
        logging.info("Removing the file as requested")
        remove(sys.argv[1])
    if keycmd_file is not None:
        remove(keycmd_file)
    sys.exit(ret)


if __name__ == '__main__':
    main()
