#!/usr/bin/env python
'''
Mercurial extension to enable purging long filenames on Windows

It's possible to have filenaems that exceed the MAX_PATH limit (256 characters)
on Windows, rendering them un-purgeable with the regular python API calls.

To work around this limitation, we can use the DeleteFileW API
(https://msdn.microsoft.com/en-us/library/windows/desktop/aa363915%28v=vs.85%29.aspx)
and prefix the filename with \\?\.

This extension needs to monkeypatch other modules in order to function. It
attempts to be very conservative, and only applies the patches for the
duration of the purge() command. The original functions are restored after
the purge() command exits.
'''
from contextlib import contextmanager
from functools import partial
import os
import errno

import mercurial.extensions
import mercurial.util

if os.name == 'nt':
    import ctypes

    # Get a reference to the DeleteFileW function
    # DeleteFileW accepts filenames encoded as a null terminated sequence of
    # wide chars (UTF-16). Python's ctypes.c_wchar_p correctly encodes unicode
    # strings to null terminated UTF-16 strings.
    # However, we receive (byte) strings from mercurial. When these are passed
    # to DeleteFileW via the c_wchar_p type, they are implicitly decoded via
    # the 'mbcs' encoding on windows.
    kernel32 = ctypes.windll.kernel32
    DeleteFile = kernel32.DeleteFileW
    DeleteFile.argtypes = [ctypes.c_wchar_p]
    DeleteFile.restype = ctypes.c_bool

    def unlink_long(fn):
        normalized_path = '\\\\?\\' + os.path.normpath(fn)
        if not DeleteFile(normalized_path):
            raise OSError(errno.EPERM, "couldn't remove long path", fn)

# Not needed on other platforms, but is handy for testing
else:
    def unlink_long(fn):
        os.unlink(fn)


def unlink_wrapper(unlink_orig, fn, ui):
    '''Calls the original unlink function, and if that fails, calls
    unlink_long'''
    try:
        ui.debug('calling unlink_orig %s\n' % fn)
        return unlink_orig(fn)
    except WindowsError, e:
        # windows error 3 corresponds to ERROR_PATH_NOT_FOUND
        # only handle this case; re-raise the exception for other kinds of
        # failures
        if e.winerror != 3:
            raise
        ui.debug('caught WindowsError ERROR_PATH_NOT_FOUND; '
                 'calling unlink_long %s\n' % fn)
        return unlink_long(fn)


@contextmanager
def wrap_unlink(ui):
    '''Context manager that patches the required functions that are used by
    the purge extension to remove files. When exiting the context manager
    the original functions are restored.'''
    version = mercurial.util.version()
    if version >= '3.2':
        # hg 3.2 and higher use util.unlink for purging
        purgemod = mercurial.extensions.find('purge')
        to_wrap = [(purgemod.util, 'unlink')]
    else:
        # hg 3.1 and earlier use os.remove directly
        to_wrap = [(os, 'remove')]

    # pass along the ui object to the unlink_wrapper so we can get logging out
    # of it
    wrapped = partial(unlink_wrapper, ui=ui)

    # Wrap the original function(s) with our unlink_wrapper
    originals = {}
    for mod, func in to_wrap:
        ui.debug('wrapping %s %s\n' % (mod, func))
        originals[mod, func] = mercurial.extensions.wrapfunction(
            mod, func, wrapped)

    try:
        yield
    finally:
        # Restore the originals
        for mod, func in to_wrap:
            ui.debug('restoring %s %s\n' % (mod, func))
            setattr(mod, func, originals[mod, func])


def purge_wrapper(orig, ui, *args, **kwargs):
    '''Runs the original purge() command inside the wrap_unlink() context
    manager.'''
    with wrap_unlink(ui):
        return orig(ui, *args, **kwargs)


def extsetup(ui):
    try:
        purgemod = mercurial.extensions.find('purge')
    except KeyError:
        ui.warn('purge extension not found; '
                'not enabling long filename support\n')
        return

    ui.note('enabling long filename support for purge\n')
    mercurial.extensions.wrapcommand(purgemod.cmdtable, 'purge', purge_wrapper)
