# !/usr/bin/env python

'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''
import getpass
import os
import random
import shlex
import subprocess
import sys
import tempfile
import time
import string

import ctypes

import msvcrt

import pywintypes
import win32api
import win32con
import win32event
import win32file
import win32net
import win32netcon
import win32process
import win32security
import win32service
import win32serviceutil
import winerror
import winioctlcon
import wmi

from ambari_commons.exceptions import FatalException
from ambari_commons.logging_utils import print_info_msg, print_warning_msg

SERVICE_STATUS_UNKNOWN = "unknown"
SERVICE_STATUS_STARTING = "starting"
SERVICE_STATUS_RUNNING = "running"
SERVICE_STATUS_STOPPING = "stopping"
SERVICE_STATUS_STOPPED = "stopped"
SERVICE_STATUS_NOT_INSTALLED = "not installed"

WHOAMI_GROUPS = "whoami /groups"
ADMIN_ACCOUNT = "BUILTIN\\Administrators"

#
# os.symlink is not implemented in Windows. Patch it.
#
__CSL = None
def symlink(source, link_name):
  '''symlink(source, link_name)
     Creates a symbolic link pointing to source named link_name'''
  global __CSL
  if __CSL is None:
    csl = ctypes.windll.kernel32.CreateSymbolicLinkW
    csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
    csl.restype = ctypes.c_ubyte
    __CSL = csl
  flags = 0
  if source is not None and os.path.isdir(source):
    flags = 1
  if __CSL(link_name, source, flags) == 0:
    raise ctypes.WinError()

os.symlink = symlink

# Win32file doesn't seem to have this attribute.
FILE_ATTRIBUTE_REPARSE_POINT = 1024
# To make things easier.
REPARSE_FOLDER = (win32file.FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)

# For the parse_reparse_buffer function
SYMBOLIC_LINK = 'symbolic'
MOUNTPOINT = 'mountpoint'
GENERIC = 'generic'

def islink(fpath):
  """ Windows islink implementation. """
  if win32file.GetFileAttributes(fpath) & REPARSE_FOLDER == REPARSE_FOLDER:
    return True
  return False

os.path.islink = islink

def _parse_reparse_buffer(original, reparse_type=SYMBOLIC_LINK):
  """ Implementing the below in Python:

  typedef struct _REPARSE_DATA_BUFFER {
      ULONG  ReparseTag;
      USHORT ReparseDataLength;
      USHORT Reserved;
      union {
          struct {
              USHORT SubstituteNameOffset;
              USHORT SubstituteNameLength;
              USHORT PrintNameOffset;
              USHORT PrintNameLength;
              ULONG Flags;
              WCHAR PathBuffer[1];
          } SymbolicLinkReparseBuffer;
          struct {
              USHORT SubstituteNameOffset;
              USHORT SubstituteNameLength;
              USHORT PrintNameOffset;
              USHORT PrintNameLength;
              WCHAR PathBuffer[1];
          } MountPointReparseBuffer;
          struct {
              UCHAR  DataBuffer[1];
          } GenericReparseBuffer;
      } DUMMYUNIONNAME;
  } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;

  """
  # Size of our data types
  SZULONG = 4 # sizeof(ULONG)
  SZUSHORT = 2 # sizeof(USHORT)

  # Our structure.
  # Probably a better way to iterate a dictionary in a particular order,
  # but I was in a hurry, unfortunately, so I used pkeys.
  buffer = {
    'tag' : SZULONG,
    'data_length' : SZUSHORT,
    'reserved' : SZUSHORT,
    SYMBOLIC_LINK : {
      'substitute_name_offset' : SZUSHORT,
      'substitute_name_length' : SZUSHORT,
      'print_name_offset' : SZUSHORT,
      'print_name_length' : SZUSHORT,
      'flags' : SZULONG,
      'buffer' : u'',
      'pkeys' : [
        'substitute_name_offset',
        'substitute_name_length',
        'print_name_offset',
        'print_name_length',
        'flags',
        ]
    },
    MOUNTPOINT : {
      'substitute_name_offset' : SZUSHORT,
      'substitute_name_length' : SZUSHORT,
      'print_name_offset' : SZUSHORT,
      'print_name_length' : SZUSHORT,
      'buffer' : u'',
      'pkeys' : [
        'substitute_name_offset',
        'substitute_name_length',
        'print_name_offset',
        'print_name_length',
        ]
    },
    GENERIC : {
      'pkeys' : [],
      'buffer': ''
    }
  }

  # Header stuff
  buffer['tag'] = original[:SZULONG]
  buffer['data_length'] = original[SZULONG:SZUSHORT]
  buffer['reserved'] = original[SZULONG+SZUSHORT:SZUSHORT]
  original = original[8:]

  # Parsing
  k = reparse_type
  for c in buffer[k]['pkeys']:
    if type(buffer[k][c]) == int:
      sz = buffer[k][c]
      bytes = original[:sz]
      buffer[k][c] = 0
      for b in bytes:
        n = ord(b)
        if n:
          buffer[k][c] += n
      original = original[sz:]

  # Using the offset and length's grabbed, we'll set the buffer.
  buffer[k]['buffer'] = original
  return buffer

def readlink(fpath):
  """ Windows readlink implementation. """
  # This wouldn't return true if the file didn't exist, as far as I know.
  if not islink(fpath):
    return None

  try:
    # Open the file correctly depending on the string type.
    if type(fpath) == unicode:
      handle = win32file.CreateFileW(fpath, win32file.GENERIC_READ, 0, None, win32file.OPEN_EXISTING, win32file.FILE_FLAG_OPEN_REPARSE_POINT | win32file.FILE_FLAG_BACKUP_SEMANTICS, 0)
    else:
      handle = win32file.CreateFile(fpath, win32file.GENERIC_READ, 0, None, win32file.OPEN_EXISTING, win32file.FILE_FLAG_OPEN_REPARSE_POINT | win32file.FILE_FLAG_BACKUP_SEMANTICS, 0)

    # MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384 = (16*1024)
    buffer = win32file.DeviceIoControl(handle, winioctlcon.FSCTL_GET_REPARSE_POINT, None, 16*1024)
    # Above will return an ugly string (byte array), so we'll need to parse it.

    # But first, we'll close the handle to our file so we're not locking it anymore.
    win32file.CloseHandle(handle)

    # Minimum possible length (assuming that the length of the target is bigger than 0)
    if len(buffer) < 9:
      return None
    # Parse and return our result.
    result = _parse_reparse_buffer(buffer)
    offset = result[SYMBOLIC_LINK]['substitute_name_offset']
    ending = offset + result[SYMBOLIC_LINK]['substitute_name_length']
    rpath = result[SYMBOLIC_LINK]['buffer'][offset:ending].replace('\x00','')
    if len(rpath) > 4 and rpath[0:4] == '\\??\\':
      rpath = rpath[4:]
    return rpath
  except pywintypes.error, e:
    raise OSError(e.winerror, e.strerror, fpath)

os.readlink = readlink


class OSVERSIONINFOEXW(ctypes.Structure):
    _fields_ = [('dwOSVersionInfoSize', ctypes.c_ulong),
                ('dwMajorVersion', ctypes.c_ulong),
                ('dwMinorVersion', ctypes.c_ulong),
                ('dwBuildNumber', ctypes.c_ulong),
                ('dwPlatformId', ctypes.c_ulong),
                ('szCSDVersion', ctypes.c_wchar*128),
                ('wServicePackMajor', ctypes.c_ushort),
                ('wServicePackMinor', ctypes.c_ushort),
                ('wSuiteMask', ctypes.c_ushort),
                ('wProductType', ctypes.c_byte),
                ('wReserved', ctypes.c_byte)]

def get_windows_version():
  """
  Gets the OS major and minor versions.  Returns a tuple of
  (OS_MAJOR, OS_MINOR).
  """
  os_version = OSVERSIONINFOEXW()
  os_version.dwOSVersionInfoSize = ctypes.sizeof(os_version)
  retcode = ctypes.windll.Ntdll.RtlGetVersion(ctypes.byref(os_version))
  if retcode != 0:
    raise Exception("Failed to get OS version")

  return os_version.dwMajorVersion, os_version.dwMinorVersion, os_version.dwBuildNumber

CHECK_FIREWALL_SCRIPT = """[string]$CName = $env:computername
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$computer)
$domain = $reg.OpenSubKey("System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile").GetValue("EnableFirewall")
$standart = $reg.OpenSubKey("System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile").GetValue("EnableFirewall")
$public = $reg.OpenSubKey("System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile").GetValue("EnableFirewall")
Write-Host $domain
Write-Host $standart
Write-Host $public
"""

def _create_tmp_files():
  out_file = tempfile.TemporaryFile(mode="r+b")
  err_file = tempfile.TemporaryFile(mode="r+b")
  return (msvcrt.get_osfhandle(out_file.fileno()),
          msvcrt.get_osfhandle(err_file.fileno()),
          out_file,
          err_file)


def _get_files_output(out, err):
  out.seek(0)
  err.seek(0)
  return out.read().strip(), err.read().strip()


def _safe_duplicate_handle(h):
  try:
    h = win32api.DuplicateHandle(win32process.GetCurrentProcess(),
                                 h,
                                 win32process.GetCurrentProcess(),
                                 0,
                                 True,
                                 win32con.DUPLICATE_SAME_ACCESS)
    return True, h
  except Exception as exc:
    if exc.winerror == winerror.ERROR_INVALID_HANDLE:
      return True, None
  return False, None


def run_os_command_impersonated(cmd, user, password, domain='.'):
  si = win32process.STARTUPINFO()

  out_handle, err_handle, out_file, err_file = _create_tmp_files()

  ok, si.hStdInput = _safe_duplicate_handle(win32api.GetStdHandle(win32api.STD_INPUT_HANDLE))

  if not ok:
    raise Exception("Unable to create StdInput for child process")
  ok, si.hStdOutput = _safe_duplicate_handle(out_handle)
  if not ok:
    raise Exception("Unable to create StdOut for child process")
  ok, si.hStdError = _safe_duplicate_handle(err_handle)
  if not ok:
    raise Exception("Unable to create StdErr for child process")

  si.dwFlags = win32process.STARTF_USESTDHANDLES
  si.lpDesktop = ""

  user_token = win32security.LogonUser(user, domain, password,
                                       win32con.LOGON32_LOGON_SERVICE, win32con.LOGON32_PROVIDER_DEFAULT)
  primary_token = win32security.DuplicateTokenEx(user_token,
                                                 win32security.SecurityImpersonation, 0, win32security.TokenPrimary)
  info = win32process.CreateProcessAsUser(primary_token, None, cmd, None, None, 1, 0, None, None, si)

  hProcess, hThread, dwProcessId, dwThreadId = info
  hThread.Close()

  try:
    win32event.WaitForSingleObject(hProcess, win32event.INFINITE)
  except KeyboardInterrupt:
    pass

  out, err = _get_files_output(out_file, err_file)
  exitcode = win32process.GetExitCodeProcess(hProcess)

  return exitcode, out, err

def os_run_os_command(cmd, env=None, shell=False, cwd=None):
  if isinstance(cmd,basestring):
    cmd = cmd.replace("\\", "\\\\")
    cmd = shlex.split(cmd)
  process = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stdin=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             env=env,
                             cwd=cwd,
                             shell=shell
  )
  (stdoutdata, stderrdata) = process.communicate()
  return process.returncode, stdoutdata, stderrdata

# execute powershell script passed in script_content. Script will be in temporary file to avoid different escape
# and formatting problems.
def run_powershell_script(script_content):
  tmp_dir = tempfile.gettempdir()
  random_filename = ''.join(random.choice(string.lowercase) for i in range(10))
  script_file = open(os.path.join(tmp_dir,random_filename+".ps1"),"w")
  script_file.write(script_content)
  script_file.close()
  result = os_run_os_command("powershell  -ExecutionPolicy unrestricted -File {0}".format(script_file.name))
  os.remove(script_file.name)
  return result

def os_change_owner(filePath, user, recursive):
  cmd = ['icacls', filePath, '/setowner', user]
  if recursive:
    cmd = ['icacls', filePath, '/t', '/setowner', user]
  retcode, outdata, errdata = os_run_os_command(cmd)
  return retcode

def os_is_root():
  '''
  Checks whether the current user is a member of the Administrators group
  Returns True if yes, otherwise False
  '''
  retcode, out, err = os_run_os_command(WHOAMI_GROUPS)
  if retcode != 0:
    err_msg = "Unable to check the current user's group memberships. " \
              "Command {0} returned exit code {1} with message: {2}".format(WHOAMI_GROUPS, retcode, err)
    print_warning_msg(err_msg)
    raise FatalException(retcode, err_msg)

  #Check for Administrators group membership
  if -1 != out.find('\n' + ADMIN_ACCOUNT):
    return True

  return False

def os_set_file_permissions(file, mod, recursive, user):
  retcode = 0

  #WARN_MSG = "Command {0} returned exit code {1} with message: {2}"
  #if recursive:
  #  params = " -R "
  #else:
  #  params = ""
  #command = NR_CHMOD_CMD.format(params, mod, file)
  #retcode, out, err = os_run_os_command(command)
  #if retcode != 0:
  #  print_warning_msg(WARN_MSG.format(command, file, err))
  #command = NR_CHOWN_CMD.format(params, user, file)
  #retcode, out, err = os_run_os_command(command)
  #if retcode != 0:
  #  print_warning_msg(WARN_MSG.format(command, file, err))

  # rights = mod
  # acls_remove_cmd = "icacls {0} /remove {1}".format(file, user)
  # retcode, out, err = os_run_os_command(acls_remove_cmd)
  # if retcode == 0:
  #   acls_modify_cmd = "icacls {0} /grant {1}:{2}".format(file, user, rights)
  #   retcode, out, err = os_run_os_command(acls_modify_cmd)
  return retcode


def os_set_open_files_limit(maxOpenFiles):
  # No open files limit in Windows. Not messing around with the System Resource Manager, at least for now.
  pass


def os_getpass(prompt, stream=None):
  """Prompt for password with echo off, using Windows getch()."""
  if sys.stdin is not sys.__stdin__:
    return getpass.fallback_getpass(prompt, stream)

  for c in prompt:
    msvcrt.putch(c)

  pw = ""
  while True:
    c = msvcrt.getch()
    if c == '\r' or c == '\n':
      break
    if c == '\003':
      raise KeyboardInterrupt
    if c == '\b':
      if pw == '':
        pass
      else:
        pw = pw[:-1]
        msvcrt.putch('\b')
        msvcrt.putch(" ")
        msvcrt.putch('\b')
    else:
      pw = pw + c
      msvcrt.putch("*")

  msvcrt.putch('\r')
  msvcrt.putch('\n')
  return pw

#[fbarca] Not used for now, keep it around just in case
def wait_for_pid_wmi(processName, parentPid, pattern, timeout):
  """
    Check pid for existence during timeout
  """
  tstart = time.time()
  pid_live = 0

  c = wmi.WMI(find_classes=False)
  qry = "select * from Win32_Process where Name=\"%s\" and ParentProcessId=%d" % (processName, parentPid)

  while int(time.time() - tstart) <= timeout:
    for proc in c.query(qry):
      cmdLine = proc.CommandLine
      if cmdLine is not None and pattern in cmdLine:
        return pid_live
    time.sleep(1)
  return 0


#need this for redirecting output form python process to file
class SyncStreamWriter(object):
  def __init__(self, stream, hMutexWrite):
    self.stream = stream
    self.hMutexWrite = hMutexWrite

  def write(self, data):
    #Ensure that the output is thread-safe when writing from 2 separate streams into the same file
    #  (typical when redirecting both stdout and stderr to the same file).
    win32event.WaitForSingleObject(self.hMutexWrite, win32event.INFINITE)
    try:
      self.stream.write(data)
      self.stream.flush()
    finally:
      win32event.ReleaseMutex(self.hMutexWrite)

  def __getattr__(self, attr):
    return getattr(self.stream, attr)


class SvcStatusCallback(object):
  def __init__(self, svc):
    self.svc = svc

  def reportStartPending(self):
    self.svc.ReportServiceStatus(win32service.SERVICE_START_PENDING)

  def reportStarted(self):
    self.svc.ReportServiceStatus(win32service.SERVICE_RUNNING)

  def reportStopPending(self):
    self.svc.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)

  def reportStopped(self):
    self.svc.ReportServiceStatus(win32service.SERVICE_STOPPED)


class WinServiceController:
  @staticmethod
  def Start(serviceName, waitSecs=30):
    err = 0
    msg = ''
    try:
      win32serviceutil.StartService(serviceName)
      if waitSecs:
        win32serviceutil.WaitForServiceStatus(serviceName, win32service.SERVICE_RUNNING, waitSecs)
    except win32service.error, exc:
      if exc.winerror != 1056:
        msg = "Error starting service: %s" % exc.strerror
        err = exc.winerror
    return err, msg

  @staticmethod
  def Stop(serviceName, waitSecs=30):
    err = 0
    msg = ''
    try:
      if waitSecs:
        win32serviceutil.StopServiceWithDeps(serviceName, waitSecs=waitSecs)
      else:
        win32serviceutil.StopService(serviceName)
      if waitSecs:
        win32serviceutil.WaitForServiceStatus(serviceName, win32service.SERVICE_STOPPED, waitSecs)
    except win32service.error, exc:
      if exc.winerror != 1062:
        msg = "Error stopping service: %s (%d)" % (exc.strerror, exc.winerror)
        err = exc.winerror
    return err, msg

  @staticmethod
  def QueryStatus(serviceName):
    statusString = SERVICE_STATUS_UNKNOWN

    try:
      status = win32serviceutil.QueryServiceStatus(serviceName)[1]

      if status == win32service.SERVICE_STOPPED:
        statusString = SERVICE_STATUS_STOPPED
      elif status == win32service.SERVICE_START_PENDING:
        statusString = SERVICE_STATUS_STARTING
      elif status == win32service.SERVICE_RUNNING:
        statusString = SERVICE_STATUS_RUNNING
      elif status == win32service.SERVICE_STOP_PENDING:
        statusString = SERVICE_STATUS_STOPPING
    except win32api.error:
      statusString = SERVICE_STATUS_NOT_INSTALLED
      pass

    return statusString

  @staticmethod
  def EnsureServiceIsStarted(serviceName, waitSecs=30):
    err = 0
    try:
      status = win32serviceutil.QueryServiceStatus(serviceName)[1]
      if win32service.SERVICE_RUNNING != status:
        if win32service.SERVICE_START_PENDING != status:
          win32serviceutil.StartService(serviceName)
        if waitSecs:
          win32serviceutil.WaitForServiceStatus(serviceName, win32service.SERVICE_RUNNING, waitSecs)
    except win32service.error, exc:
      if exc.winerror != 1056:
        err = exc.winerror
    return err


class WinService(win32serviceutil.ServiceFramework):
  # _svc_name_ = The service name
  # _svc_display_name_ = The service display name
  # _svc_description_ = The service description

  _heventSvcStop = win32event.CreateEvent(None, 1, 0, None)
  _hmtxOut = win32event.CreateMutex(None, False, None)  #[fbarca] Python doesn't support critical sections

  def __init__(self, *args):
    win32serviceutil.ServiceFramework.__init__(self, *args)

  def SvcDoRun(self):
    try:
      self.ReportServiceStatus(win32service.SERVICE_RUNNING)
      self.ServiceMain()
    except Exception, x:
      #TODO: Log exception
      self.SvcStop()

  def SvcStop(self):
    self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
    win32event.SetEvent(WinService._heventSvcStop)

  # Service code entry point. Override it to implement the intended functionality.
  def ServiceMain(self):
    #Default implementation, does nothing.
    win32event.WaitForSingleObject(WinService._heventSvcStop, win32event.INFINITE)
    pass

  @staticmethod
  def DefCtrlCHandler():
    print_info_msg("Ctrl+C handler invoked. Stopping.")
    win32event.SetEvent(WinService._heventSvcStop)
    pass

  #username domain\\username : The Username the service is to run under
  #password password : The password for the username
  #startup [manual|auto|disabled|delayed] : How the service starts, default = auto
  #interactive : Allow the service to interact with the desktop.
  #perfmonini file: .ini file to use for registering performance monitor data
  #perfmondll file: .dll file to use when querying the service for performance data, default = perfmondata.dll
  @classmethod
  def Install(cls, classPath = None, startupMode = "auto", username = None, password = None, interactive = False,
              perfMonIni = None, perfMonDll = None):
    installArgs = [sys.argv[0], "--startup=" + startupMode]
    if username is not None and username:
      if username.find('\\') == -1:
        username = '.\\' + username
      installArgs.append("--username=" + username)
      if password is not None and password:
        installArgs.append("--password=" + password)
    if interactive:
      installArgs.append("--interactive")
    if perfMonIni is not None and perfMonIni:
      installArgs.append("--perfmonini=" + perfMonIni)
    if perfMonDll is not None and perfMonDll:
      installArgs.append("--perfmondll=" + perfMonDll)
    installArgs.append("install")

    return win32serviceutil.HandleCommandLine(cls, classPath, installArgs)

  @classmethod
  def Start(cls, waitSecs = 30):
    return WinServiceController.Start(cls._svc_name_, waitSecs)

  @classmethod
  def Stop(cls, waitSecs = 30):
    return WinServiceController.Stop(cls._svc_name_, waitSecs)

  @classmethod
  def QueryStatus(cls):
    return WinServiceController.QueryStatus(cls._svc_name_)

  @classmethod
  def set_ctrl_c_handler(cls, ctrlHandler):
    win32api.SetConsoleCtrlHandler(ctrlHandler, True)
    pass

  def _RedirectOutputStreamsToFile(self, outFilePath):
    outFileDir = os.path.dirname(outFilePath)
    if not os.path.exists(outFileDir):
      os.makedirs(outFileDir)

    out_writer = SyncStreamWriter(file(outFilePath, "w"), self._hmtxOut)
    sys.stderr = out_writer
    sys.stdout = out_writer
    pass

  def CheckForStop(self):
    #Check for stop event to be signaled
    return win32event.WAIT_OBJECT_0 == win32event.WaitForSingleObject(WinService._heventSvcStop, 1)

  def _StopOrWaitForChildProcessToFinish(self, childProcess):
    #Wait for the child process to finish or for the stop event to be signaled
    if(win32event.WAIT_OBJECT_0 == win32event.WaitForMultipleObjects([WinService._heventSvcStop, childProcess._handle],
                                                                     False, win32event.INFINITE)):
      # The OS only detaches the child process when the master process exits.
      # We must kill it manually.
      try:
        #Sending signal.CTRL_BREAK_EVENT doesn't work. It only detaches the child process from the master.
        #  Must brutally terminate the child process. Sorry Java.
        childProcess.terminate()
      except OSError, e:
        print_info_msg("Unable to stop Ambari Server - " + str(e))
        return False

    return True

class SystemWideLock(object):

  def __init__(self, name):
    self._mutex = win32event.CreateMutex(None, 0, name)

  def lock(self, timeout=0):
    result = win32event.WaitForSingleObject(self._mutex, timeout)
    if result in [win32event.WAIT_TIMEOUT, win32event.WAIT_ABANDONED, win32event.WAIT_FAILED]:
      return False
    elif result == win32event.WAIT_OBJECT_0:
      return True

  def unlock(self):
    try:
      win32event.ReleaseMutex(self._mutex)
      return True
    except:
      return False

  def __del__(self):
    win32api.CloseHandle(self._mutex)

class UserHelper(object):
  ACTION_OK = 0
  USER_EXISTS = 1
  ACTION_FAILED = -1

  def __init__(self, userName):
    self.domainName, self.userName = UserHelper.parse_user_name(userName)
    if self.domainName:
      self.dcName = win32net.NetGetDCName(None, self.domainName)
    else:
      self.dcName = None
    self._policy = win32security.LsaOpenPolicy(self.dcName,
                                               win32security.POLICY_CREATE_ACCOUNT | win32security.POLICY_LOOKUP_NAMES)

  @staticmethod
  def parse_user_name(userName, defDomain=None):
    domainName = defDomain
    domainSepIndex = userName.find('\\')
    if domainSepIndex != -1:
      domainName = userName[0:domainSepIndex]
      userName = userName[domainSepIndex + 1:]
      if not domainName or domainName == '.' or domainName == win32api.GetComputerName():
        domainName = defDomain
    return (domainName, userName)

  def create_user(self, password, comment="Ambari user"):
    user_info = {}
    user_info['name'] = self.userName
    user_info['password'] = password
    user_info['priv'] = win32netcon.USER_PRIV_USER
    user_info['comment'] = comment
    user_info['flags'] = win32netcon.UF_NORMAL_ACCOUNT | win32netcon.UF_SCRIPT
    try:
      win32net.NetUserAdd(self.dcName, 1, user_info)
    except pywintypes.error as e:
      if e.winerror == 2224:
        return UserHelper.USER_EXISTS, e.strerror
      else:
        return UserHelper.ACTION_FAILED, e.strerror
    return UserHelper.ACTION_OK, "User created."

  def find_user(self):
    try:
      user_info = win32net.NetUserGetInfo(self.dcName, self.userName, 0)
    except pywintypes.error as e:
      if e.winerror == 2221:
        return False
      else:
        raise
    return True

  def add_user_privilege(self, privilege):
    try:
      acc_sid = win32security.LookupAccountName(self.dcName, self.userName)[0]
      win32security.LsaAddAccountRights(self._policy, acc_sid, (privilege,))
    except pywintypes.error as e:
      return UserHelper.ACTION_FAILED, e.strerror
    return UserHelper.ACTION_OK, "Privilege added."

  def remove_user_privilege(self, name, privilege):
    try:
      acc_sid = win32security.LookupAccountName(self.dcName, self.userName)[0]
      win32security.LsaRemoveAccountRights(self._policy, acc_sid, 0, (privilege,))
    except pywintypes.error as e:
      return UserHelper.ACTION_FAILED, e.strerror
    return UserHelper.ACTION_OK, "Privilege removed."
