# coding=utf-8

from __future__ import absolute_import
from __future__ import print_function
import subprocess
import sys
import traceback
import logging
import re
import binascii
import types
import os

from shlex import quote
from .lib import find_executable

mswindows = False
if sys.platform == "win32":
    mswindows = True
    from pyads import ADS

logger = logging.getLogger(__name__)


def quote_args(seq):
    return ' '.join(quote(arg) for arg in seq)


def win32_xattr(fn):
    handler = ADS(fn)
    try:
        return handler.get_stream_content("net.filebot.filename")
    except IOError:
        pass


def default_xattr(fn):
    if not default_xattr_bin:
        raise Exception("Neither getfattr, attr nor filebot were found")

    if "getfattr" in default_xattr_bin:
        return ["getfattr", "-n", "user.net.filebot.filename", fn]

    elif "attr" in default_xattr_bin:
        return ["attr", "-g", "net.filebot.filename", fn]

    return ["filebot", "-script", "fn:xattr", fn]


XATTR_MAP = {
    "default": (
        default_xattr,
        lambda result: re.search(r'(?um)(net\.filebot\.filename(?=="|: )[=:" ]+|Attribute.+:\s)([^"\n\r\0]+)',
                                 result).group(2)
    ),
    # "darwin": (
    #     lambda fn: ["xattr", "-p", "net.filebot.filename", fn],
    #     lambda result: binascii.unhexlify(result.strip().replace(' ', '').replace('\r\n', '').replace('\r', '')
    #                                       .replace('\n', '')).strip("\x00")
    # ),
    "darwin": (
        lambda fn: ["filebot", "-script", "fn:xattr", fn],
        lambda result: re.search(r'(?um)(net\.filebot\.filename(?=="|: )[=:" ]+|Attribute.+:\s)([^"\n\r\0]+)',
                                 result).group(2)
    ),
    "win32": (
        lambda fn: fn,
        win32_xattr,
    )
}

if sys.platform not in XATTR_MAP:
    default_xattr_bin = find_executable("getfattr") or find_executable("attr") or find_executable("filebot") \
                        or "filebot"


def get_filebot_attrs(fn):
    """
    Currently only supports the filebot filename attrs
    :param fn: filename
    :return:
    """

    if sys.platform in XATTR_MAP:
        logger.debug("Using native xattr calls for %s", sys.platform)
    else:
        logger.debug("Using %s for %s", default_xattr_bin, sys.platform)

    args_func, match_func = XATTR_MAP.get(sys.platform, XATTR_MAP["default"])

    args = args_func(fn)
    if isinstance(args, list):
        try:
            env = dict(os.environ)
            if not mswindows:
                env_path = {"PATH": os.pathsep.join(
                    [
                        "/usr/local/bin",
                        "/usr/bin",
                        "/usr/local/sbin",
                        "/usr/sbin",
                        os.environ.get("PATH", "")
                    ]
                )
                }
                env = dict(os.environ, **env_path)

            env.pop("LD_LIBRARY_PATH", None)

            proc = subprocess.Popen(quote_args(args), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True,
                                    env=env)
            output, errors = proc.communicate()

            if proc.returncode == 1:
                logger.info(u"%s: Couldn't get filebot original filename, args: %r, output: %r, error: %r", fn, args,
                            output, errors)
                return

            output = output.decode()

        except:
            logger.error(u"%s: Unexpected error while getting filebot original filename: %s", fn,
                             traceback.format_exc())
            return
    else:
        output = args

    try:
        orig_fn = match_func(output)
        return orig_fn.strip()
    except:
        logger.info(u"%s: Couldn't get filebot original filename" % fn)
        logger.debug(u"%s: Result: %r" % (fn, output))


if __name__ == "__main__":
    print(get_filebot_attrs(sys.argv[1]))
