# -*- coding: utf-8 -*-
#
# Copyright © 2012 Pierre Raybaut
# Licensed under the terms of the MIT License
# (see winpython/__init__.py for details)

"""
Register a Python distribution

Created on Tue Aug 21 21:46:30 2012
"""

from __future__ import print_function

import sys
import os
import os.path as osp
import subprocess


# Local imports
from winpython.py3compat import winreg
from winpython import utils

KEY_C = r"Software\Classes\%s"
KEY_C0 = KEY_C % r"Python.%sFile\shell"
KEY_C1 = KEY_C % r"Python.%sFile\shell\%s"
KEY_C2 = KEY_C1 + r"\command"
KEY_DROP0 = KEY_C % r"Python.%sFile\shellex"
KEY_DROP1 = KEY_C % r"Python.%sFile\shellex\DropHandler"
KEY_I = KEY_C % r"Python.%sFile\DefaultIcon"
KEY_D = KEY_C % r"Python.%sFile"
EWI = "Edit with IDLE"
EWS = "Edit with Spyder"

KEY_S = r"Software\Python"
KEY_S0 = KEY_S + r"\PythonCore"
KEY_S1 = KEY_S0 + r"\%s"


def _get_shortcut_data(target, current=True):
    wpgroup = utils.create_winpython_start_menu_folder(
        current=current
    )
    wpdir = osp.join(target, os.pardir)
    data = []
    for name in os.listdir(wpdir):
        bname, ext = osp.splitext(name)
        if ext == '.exe':
            data.append(
                (
                    osp.join(wpdir, name),
                    bname,
                    osp.join(wpgroup, bname),
                )
            )
    return data


def register(target, current=True):
    """Register a Python distribution in Windows registry"""
    root = (
        winreg.HKEY_CURRENT_USER
        if current
        else winreg.HKEY_LOCAL_MACHINE
    )

    # Extensions
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".py"),
        "",
        0,
        winreg.REG_SZ,
        "Python.File",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".pyw"),
        "",
        0,
        winreg.REG_SZ,
        "Python.NoConFile",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".pyc"),
        "",
        0,
        winreg.REG_SZ,
        "Python.CompiledFile",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".pyo"),
        "",
        0,
        winreg.REG_SZ,
        "Python.CompiledFile",
    )

    # MIME types
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".py"),
        "Content Type",
        0,
        winreg.REG_SZ,
        "text/plain",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C % ".pyw"),
        "Content Type",
        0,
        winreg.REG_SZ,
        "text/plain",
    )

    # Verbs
    python = osp.abspath(osp.join(target, 'python.exe'))
    pythonw = osp.abspath(osp.join(target, 'pythonw.exe'))
    spyder = osp.abspath(
        osp.join(target, os.pardir, 'Spyder.exe')
    )
    if not osp.isfile(spyder):
        spyder = '%s" "%s\Scripts\spyder' % (
            pythonw,
            target,
        )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("", "open")),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1" %%*' % python,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("NoCon", "open")),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1" %%*' % pythonw,
    )
    winreg.SetValueEx(
        winreg.CreateKey(
            root, KEY_C2 % ("Compiled", "open")
        ),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1" %%*' % python,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("", EWI)),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"'
        % (pythonw, target),
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("NoCon", EWI)),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%s\Lib\idlelib\idle.pyw" -n -e "%%1"'
        % (pythonw, target),
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("", EWS)),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1"' % spyder,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_C2 % ("NoCon", EWS)),
        "",
        0,
        winreg.REG_SZ,
        '"%s" "%%1"' % spyder,
    )

    # Drop support
    handler = "{60254CA5-953B-11CF-8C96-00AA00B8708C}"
    for ftype in ("", "NoCon", "Compiled"):
        winreg.SetValueEx(
            winreg.CreateKey(root, KEY_DROP1 % ftype),
            "",
            0,
            winreg.REG_SZ,
            handler,
        )
    # Icons
    dlls = osp.join(target, 'DLLs')
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_I % ""),
        "",
        0,
        winreg.REG_SZ,
        r'%s\py.ico' % dlls,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_I % "NoCon"),
        "",
        0,
        winreg.REG_SZ,
        r'%s\py.ico' % dlls,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_I % "Compiled"),
        "",
        0,
        winreg.REG_SZ,
        r'%s\pyc.ico' % dlls,
    )

    # Descriptions
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_D % ""),
        "",
        0,
        winreg.REG_SZ,
        "Python File",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_D % "NoCon"),
        "",
        0,
        winreg.REG_SZ,
        "Python File (no console)",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, KEY_D % "Compiled"),
        "",
        0,
        winreg.REG_SZ,
        "Compiled Python File",
    )

    # PythonCore entries
    short_version = utils.get_python_infos(target)[0]
    long_version = utils.get_python_long_version(target)
    key_core = (KEY_S1 % short_version) + r'\%s'
    winreg.SetValueEx(
        winreg.CreateKey(root, key_core % 'InstallPath'),
        "",
        0,
        winreg.REG_SZ,
        target,
    )
    winreg.SetValueEx(
        winreg.CreateKey(
            root, key_core % r'InstallPath\InstallGroup'
        ),
        "",
        0,
        winreg.REG_SZ,
        "Python %s" % short_version,
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, key_core % 'Modules'),
        "",
        0,
        winreg.REG_SZ,
        "",
    )
    winreg.SetValueEx(
        winreg.CreateKey(root, key_core % 'PythonPath'),
        "",
        0,
        winreg.REG_SZ,
        r"%s\Lib;%s\DLLs" % (target, target),
    )
    winreg.SetValueEx(
        winreg.CreateKey(
            root,
            key_core % r'Help\Main Python Documentation',
        ),
        "",
        0,
        winreg.REG_SZ,
        r"%s\Doc\python%s.chm" % (target, long_version),
    )

    # Create start menu entries for all WinPython launchers
    for path, desc, fname in _get_shortcut_data(
        target, current=current
    ):
        utils.create_shortcut(path, desc, fname)
    # Register the Python ActiveX Scripting client (requires pywin32)
    axscript = osp.join(
        target,
        'Lib',
        'site-packages',
        'win32comext',
        'axscript',
        'client',
        'pyscript.py',
    )
    if osp.isfile(axscript):
        subprocess.call(
            '"%s" "%s"' % (python, axscript), cwd=target
        )
    else:
        print(
            'Unable to register ActiveX: please install pywin32',
            file=sys.stderr,
        )


def unregister(target, current=True):
    """Unregister a Python distribution in Windows registry"""
    # Registry entries
    root = (
        winreg.HKEY_CURRENT_USER
        if current
        else winreg.HKEY_LOCAL_MACHINE
    )
    short_version = utils.get_python_infos(target)[0]
    key_core = (KEY_S1 % short_version) + r'\%s'
    for key in (
        # Drop support
        KEY_DROP1 % "",
        KEY_DROP1 % "NoCon",
        KEY_DROP1 % "Compiled",
        KEY_DROP0 % "",
        KEY_DROP0 % "NoCon",
        KEY_DROP0 % "Compiled",
        # Icons
        KEY_I % "NoCon",
        KEY_I % "Compiled",
        KEY_I % "",
        # Edit with IDLE
        KEY_C2 % ("", EWI),
        KEY_C2 % ("NoCon", EWI),
        KEY_C1 % ("", EWI),
        KEY_C1 % ("NoCon", EWI),
        # Edit with Spyder
        KEY_C2 % ("", EWS),
        KEY_C2 % ("NoCon", EWS),
        KEY_C1 % ("", EWS),
        KEY_C1 % ("NoCon", EWS),
        # Verbs
        KEY_C2 % ("", "open"),
        KEY_C2 % ("NoCon", "open"),
        KEY_C2 % ("Compiled", "open"),
        KEY_C1 % ("", "open"),
        KEY_C1 % ("NoCon", "open"),
        KEY_C1 % ("Compiled", "open"),
        KEY_C0 % "",
        KEY_C0 % "NoCon",
        KEY_C0 % "Compiled",
        # Descriptions
        KEY_D % "NoCon",
        KEY_D % "Compiled",
        KEY_D % "",
        # PythonCore
        key_core % r'InstallPath\InstallGroup',
        key_core % 'InstallPath',
        key_core % 'Modules',
        key_core % 'PythonPath',
        key_core % r'Help\Main Python Documentation',
        key_core % 'Help',
        KEY_S1 % short_version,
        KEY_S0,
        KEY_S,
    ):
        try:
            print(key)
            winreg.DeleteKey(root, key)
        except WindowsError:
            rootkey = (
                'HKEY_CURRENT_USER'
                if current
                else 'HKEY_LOCAL_MACHINE'
            )
            print(
                r'Unable to remove %s\%s' % (rootkey, key),
                file=sys.stderr,
            )
    # Start menu shortcuts
    for path, desc, fname in _get_shortcut_data(
        target, current=current
    ):
        if osp.exists(fname):
            os.remove(fname)


if __name__ == '__main__':
    register(sys.prefix)
    unregister(sys.prefix)
