// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build windows

// Package mgr can be used to manage Windows service programs.
// It can be used to install and remove them. It can also start,
// stop and pause them. The package can query / change current
// service state and config parameters.
package mgr

import (
	"syscall"
	"time"
	"unicode/utf16"
	"unsafe"

	"golang.org/x/sys/windows"
)

// Mgr is used to manage Windows service.
type Mgr struct {
	Handle windows.Handle
}

// Connect establishes a connection to the service control manager.
func Connect() (*Mgr, error) {
	return ConnectRemote("")
}

// ConnectRemote establishes a connection to the
// service control manager on computer named host.
func ConnectRemote(host string) (*Mgr, error) {
	var s *uint16
	if host != "" {
		var err error
		s, err = syscall.UTF16PtrFromString(host)
		if err != nil {
			return nil, err
		}
	}
	h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS)
	if err != nil {
		return nil, err
	}
	return &Mgr{Handle: h}, nil
}

// Disconnect closes connection to the service control manager m.
func (m *Mgr) Disconnect() error {
	return windows.CloseServiceHandle(m.Handle)
}

type LockStatus struct {
	IsLocked bool          // Whether the SCM has been locked.
	Age      time.Duration // For how long the SCM has been locked.
	Owner    string        // The name of the user who has locked the SCM.
}

// LockStatus returns whether the service control manager is locked by
// the system, for how long, and by whom. A locked SCM indicates that
// most service actions will block until the system unlocks the SCM.
func (m *Mgr) LockStatus() (*LockStatus, error) {
	bytesNeeded := uint32(unsafe.Sizeof(windows.QUERY_SERVICE_LOCK_STATUS{}) + 1024)
	for {
		bytes := make([]byte, bytesNeeded)
		lockStatus := (*windows.QUERY_SERVICE_LOCK_STATUS)(unsafe.Pointer(&bytes[0]))
		err := windows.QueryServiceLockStatus(m.Handle, lockStatus, uint32(len(bytes)), &bytesNeeded)
		if err == windows.ERROR_INSUFFICIENT_BUFFER && bytesNeeded >= uint32(unsafe.Sizeof(windows.QUERY_SERVICE_LOCK_STATUS{})) {
			continue
		}
		if err != nil {
			return nil, err
		}
		status := &LockStatus{
			IsLocked: lockStatus.IsLocked != 0,
			Age:      time.Duration(lockStatus.LockDuration) * time.Second,
			Owner:    windows.UTF16PtrToString(lockStatus.LockOwner),
		}
		return status, nil
	}
}

func toPtr(s string) (*uint16, error) {
	if len(s) == 0 {
		return nil, nil
	}
	return syscall.UTF16PtrFromString(s)
}

// toStringBlock terminates strings in ss with 0, and then
// concatenates them together. It also adds extra 0 at the end.
func toStringBlock(ss []string) *uint16 {
	if len(ss) == 0 {
		return nil
	}
	t := ""
	for _, s := range ss {
		if s != "" {
			t += s + "\x00"
		}
	}
	if t == "" {
		return nil
	}
	t += "\x00"
	return &utf16.Encode([]rune(t))[0]
}

// CreateService installs new service name on the system.
// The service will be executed by running exepath binary.
// Use config c to specify service parameters.
// Any args will be passed as command-line arguments when
// the service is started; these arguments are distinct from
// the arguments passed to Service.Start or via the "Start
// parameters" field in the service's Properties dialog box.
func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Service, error) {
	if c.StartType == 0 {
		c.StartType = StartManual
	}
	if c.ServiceType == 0 {
		c.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
	}
	s := syscall.EscapeArg(exepath)
	for _, v := range args {
		s += " " + syscall.EscapeArg(v)
	}
	namePointer, err := toPtr(name)
	if err != nil {
		return nil, err
	}
	displayNamePointer, err := toPtr(c.DisplayName)
	if err != nil {
		return nil, err
	}
	sPointer, err := toPtr(s)
	if err != nil {
		return nil, err
	}
	loadOrderGroupPointer, err := toPtr(c.LoadOrderGroup)
	if err != nil {
		return nil, err
	}
	serviceStartNamePointer, err := toPtr(c.ServiceStartName)
	if err != nil {
		return nil, err
	}
	passwordPointer, err := toPtr(c.Password)
	if err != nil {
		return nil, err
	}
	h, err := windows.CreateService(m.Handle, namePointer, displayNamePointer,
		windows.SERVICE_ALL_ACCESS, c.ServiceType,
		c.StartType, c.ErrorControl, sPointer, loadOrderGroupPointer,
		nil, toStringBlock(c.Dependencies), serviceStartNamePointer, passwordPointer)
	if err != nil {
		return nil, err
	}
	if c.SidType != windows.SERVICE_SID_TYPE_NONE {
		err = updateSidType(h, c.SidType)
		if err != nil {
			windows.DeleteService(h)
			windows.CloseServiceHandle(h)
			return nil, err
		}
	}
	if c.Description != "" {
		err = updateDescription(h, c.Description)
		if err != nil {
			windows.DeleteService(h)
			windows.CloseServiceHandle(h)
			return nil, err
		}
	}
	if c.DelayedAutoStart {
		err = updateStartUp(h, c.DelayedAutoStart)
		if err != nil {
			windows.DeleteService(h)
			windows.CloseServiceHandle(h)
			return nil, err
		}
	}
	return &Service{Name: name, Handle: h}, nil
}

// OpenService retrieves access to service name, so it can
// be interrogated and controlled.
func (m *Mgr) OpenService(name string) (*Service, error) {
	namePointer, err := syscall.UTF16PtrFromString(name)
	if err != nil {
		return nil, err
	}

	h, err := windows.OpenService(m.Handle, namePointer, windows.SERVICE_ALL_ACCESS)
	if err != nil {
		return nil, err
	}
	return &Service{Name: name, Handle: h}, nil
}

// ListServices enumerates services in the specified
// service control manager database m.
// If the caller does not have the SERVICE_QUERY_STATUS
// access right to a service, the service is silently
// omitted from the list of services returned.
func (m *Mgr) ListServices() ([]string, error) {
	var err error
	var bytesNeeded, servicesReturned uint32
	var buf []byte
	for {
		var p *byte
		if len(buf) > 0 {
			p = &buf[0]
		}
		err = windows.EnumServicesStatusEx(m.Handle, windows.SC_ENUM_PROCESS_INFO,
			windows.SERVICE_WIN32, windows.SERVICE_STATE_ALL,
			p, uint32(len(buf)), &bytesNeeded, &servicesReturned, nil, nil)
		if err == nil {
			break
		}
		if err != syscall.ERROR_MORE_DATA {
			return nil, err
		}
		if bytesNeeded <= uint32(len(buf)) {
			return nil, err
		}
		buf = make([]byte, bytesNeeded)
	}
	if servicesReturned == 0 {
		return nil, nil
	}
	services := unsafe.Slice((*windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0])), int(servicesReturned))

	var names []string
	for _, s := range services {
		name := windows.UTF16PtrToString(s.ServiceName)
		names = append(names, name)
	}
	return names, nil
}
