// 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
// +build windows

// Package svc provides everything required to build Windows service.
package svc

import (
	"errors"
	"sync"
	"unsafe"

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

// State describes service execution state (Stopped, Running and so on).
type State uint32

const (
	Stopped         = State(windows.SERVICE_STOPPED)
	StartPending    = State(windows.SERVICE_START_PENDING)
	StopPending     = State(windows.SERVICE_STOP_PENDING)
	Running         = State(windows.SERVICE_RUNNING)
	ContinuePending = State(windows.SERVICE_CONTINUE_PENDING)
	PausePending    = State(windows.SERVICE_PAUSE_PENDING)
	Paused          = State(windows.SERVICE_PAUSED)
)

// Cmd represents service state change request. It is sent to a service
// by the service manager, and should be actioned upon by the service.
type Cmd uint32

const (
	Stop                  = Cmd(windows.SERVICE_CONTROL_STOP)
	Pause                 = Cmd(windows.SERVICE_CONTROL_PAUSE)
	Continue              = Cmd(windows.SERVICE_CONTROL_CONTINUE)
	Interrogate           = Cmd(windows.SERVICE_CONTROL_INTERROGATE)
	Shutdown              = Cmd(windows.SERVICE_CONTROL_SHUTDOWN)
	ParamChange           = Cmd(windows.SERVICE_CONTROL_PARAMCHANGE)
	NetBindAdd            = Cmd(windows.SERVICE_CONTROL_NETBINDADD)
	NetBindRemove         = Cmd(windows.SERVICE_CONTROL_NETBINDREMOVE)
	NetBindEnable         = Cmd(windows.SERVICE_CONTROL_NETBINDENABLE)
	NetBindDisable        = Cmd(windows.SERVICE_CONTROL_NETBINDDISABLE)
	DeviceEvent           = Cmd(windows.SERVICE_CONTROL_DEVICEEVENT)
	HardwareProfileChange = Cmd(windows.SERVICE_CONTROL_HARDWAREPROFILECHANGE)
	PowerEvent            = Cmd(windows.SERVICE_CONTROL_POWEREVENT)
	SessionChange         = Cmd(windows.SERVICE_CONTROL_SESSIONCHANGE)
	PreShutdown           = Cmd(windows.SERVICE_CONTROL_PRESHUTDOWN)
)

// Accepted is used to describe commands accepted by the service.
// Note that Interrogate is always accepted.
type Accepted uint32

const (
	AcceptStop                  = Accepted(windows.SERVICE_ACCEPT_STOP)
	AcceptShutdown              = Accepted(windows.SERVICE_ACCEPT_SHUTDOWN)
	AcceptPauseAndContinue      = Accepted(windows.SERVICE_ACCEPT_PAUSE_CONTINUE)
	AcceptParamChange           = Accepted(windows.SERVICE_ACCEPT_PARAMCHANGE)
	AcceptNetBindChange         = Accepted(windows.SERVICE_ACCEPT_NETBINDCHANGE)
	AcceptHardwareProfileChange = Accepted(windows.SERVICE_ACCEPT_HARDWAREPROFILECHANGE)
	AcceptPowerEvent            = Accepted(windows.SERVICE_ACCEPT_POWEREVENT)
	AcceptSessionChange         = Accepted(windows.SERVICE_ACCEPT_SESSIONCHANGE)
	AcceptPreShutdown           = Accepted(windows.SERVICE_ACCEPT_PRESHUTDOWN)
)

// ActivityStatus allows for services to be selected based on active and inactive categories of service state.
type ActivityStatus uint32

const (
	Active      = ActivityStatus(windows.SERVICE_ACTIVE)
	Inactive    = ActivityStatus(windows.SERVICE_INACTIVE)
	AnyActivity = ActivityStatus(windows.SERVICE_STATE_ALL)
)

// Status combines State and Accepted commands to fully describe running service.
type Status struct {
	State                   State
	Accepts                 Accepted
	CheckPoint              uint32 // used to report progress during a lengthy operation
	WaitHint                uint32 // estimated time required for a pending operation, in milliseconds
	ProcessId               uint32 // if the service is running, the process identifier of it, and otherwise zero
	Win32ExitCode           uint32 // set if the service has exited with a win32 exit code
	ServiceSpecificExitCode uint32 // set if the service has exited with a service-specific exit code
}

// StartReason is the reason that the service was started.
type StartReason uint32

const (
	StartReasonDemand           = StartReason(windows.SERVICE_START_REASON_DEMAND)
	StartReasonAuto             = StartReason(windows.SERVICE_START_REASON_AUTO)
	StartReasonTrigger          = StartReason(windows.SERVICE_START_REASON_TRIGGER)
	StartReasonRestartOnFailure = StartReason(windows.SERVICE_START_REASON_RESTART_ON_FAILURE)
	StartReasonDelayedAuto      = StartReason(windows.SERVICE_START_REASON_DELAYEDAUTO)
)

// ChangeRequest is sent to the service Handler to request service status change.
type ChangeRequest struct {
	Cmd           Cmd
	EventType     uint32
	EventData     uintptr
	CurrentStatus Status
	Context       uintptr
}

// Handler is the interface that must be implemented to build Windows service.
type Handler interface {
	// Execute will be called by the package code at the start of
	// the service, and the service will exit once Execute completes.
	// Inside Execute you must read service change requests from r and
	// act accordingly. You must keep service control manager up to date
	// about state of your service by writing into s as required.
	// args contains service name followed by argument strings passed
	// to the service.
	// You can provide service exit code in exitCode return parameter,
	// with 0 being "no error". You can also indicate if exit code,
	// if any, is service specific or not by using svcSpecificEC
	// parameter.
	Execute(args []string, r <-chan ChangeRequest, s chan<- Status) (svcSpecificEC bool, exitCode uint32)
}

type ctlEvent struct {
	cmd       Cmd
	eventType uint32
	eventData uintptr
	context   uintptr
	errno     uint32
}

// service provides access to windows service api.
type service struct {
	name    string
	h       windows.Handle
	c       chan ctlEvent
	handler Handler
}

type exitCode struct {
	isSvcSpecific bool
	errno         uint32
}

func (s *service) updateStatus(status *Status, ec *exitCode) error {
	if s.h == 0 {
		return errors.New("updateStatus with no service status handle")
	}
	var t windows.SERVICE_STATUS
	t.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
	t.CurrentState = uint32(status.State)
	if status.Accepts&AcceptStop != 0 {
		t.ControlsAccepted |= windows.SERVICE_ACCEPT_STOP
	}
	if status.Accepts&AcceptShutdown != 0 {
		t.ControlsAccepted |= windows.SERVICE_ACCEPT_SHUTDOWN
	}
	if status.Accepts&AcceptPauseAndContinue != 0 {
		t.ControlsAccepted |= windows.SERVICE_ACCEPT_PAUSE_CONTINUE
	}
	if status.Accepts&AcceptParamChange != 0 {
		t.ControlsAccepted |= windows.SERVICE_ACCEPT_PARAMCHANGE
	}
	if status.Accepts&AcceptNetBindChange != 0 {
		t.ControlsAccepted |= windows.SERVICE_ACCEPT_NETBINDCHANGE
	}
	if status.Accepts&AcceptHardwareProfileChange != 0 {
		t.ControlsAccepted |= windows.SERVICE_ACCEPT_HARDWAREPROFILECHANGE
	}
	if status.Accepts&AcceptPowerEvent != 0 {
		t.ControlsAccepted |= windows.SERVICE_ACCEPT_POWEREVENT
	}
	if status.Accepts&AcceptSessionChange != 0 {
		t.ControlsAccepted |= windows.SERVICE_ACCEPT_SESSIONCHANGE
	}
	if status.Accepts&AcceptPreShutdown != 0 {
		t.ControlsAccepted |= windows.SERVICE_ACCEPT_PRESHUTDOWN
	}
	if ec.errno == 0 {
		t.Win32ExitCode = windows.NO_ERROR
		t.ServiceSpecificExitCode = windows.NO_ERROR
	} else if ec.isSvcSpecific {
		t.Win32ExitCode = uint32(windows.ERROR_SERVICE_SPECIFIC_ERROR)
		t.ServiceSpecificExitCode = ec.errno
	} else {
		t.Win32ExitCode = ec.errno
		t.ServiceSpecificExitCode = windows.NO_ERROR
	}
	t.CheckPoint = status.CheckPoint
	t.WaitHint = status.WaitHint
	return windows.SetServiceStatus(s.h, &t)
}

var (
	initCallbacks       sync.Once
	ctlHandlerCallback  uintptr
	serviceMainCallback uintptr
)

func ctlHandler(ctl, evtype, evdata, context uintptr) uintptr {
	s := (*service)(unsafe.Pointer(context))
	e := ctlEvent{cmd: Cmd(ctl), eventType: uint32(evtype), eventData: evdata, context: 123456} // Set context to 123456 to test issue #25660.
	s.c <- e
	return 0
}

var theService service // This is, unfortunately, a global, which means only one service per process.

// serviceMain is the entry point called by the service manager, registered earlier by
// the call to StartServiceCtrlDispatcher.
func serviceMain(argc uint32, argv **uint16) uintptr {
	handle, err := windows.RegisterServiceCtrlHandlerEx(windows.StringToUTF16Ptr(theService.name), ctlHandlerCallback, uintptr(unsafe.Pointer(&theService)))
	if sysErr, ok := err.(windows.Errno); ok {
		return uintptr(sysErr)
	} else if err != nil {
		return uintptr(windows.ERROR_UNKNOWN_EXCEPTION)
	}
	theService.h = handle
	defer func() {
		theService.h = 0
	}()
	var args16 []*uint16
	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&args16))
	hdr.Data = unsafe.Pointer(argv)
	hdr.Len = int(argc)
	hdr.Cap = int(argc)

	args := make([]string, len(args16))
	for i, a := range args16 {
		args[i] = windows.UTF16PtrToString(a)
	}

	cmdsToHandler := make(chan ChangeRequest)
	changesFromHandler := make(chan Status)
	exitFromHandler := make(chan exitCode)

	go func() {
		ss, errno := theService.handler.Execute(args, cmdsToHandler, changesFromHandler)
		exitFromHandler <- exitCode{ss, errno}
	}()

	ec := exitCode{isSvcSpecific: true, errno: 0}
	outcr := ChangeRequest{
		CurrentStatus: Status{State: Stopped},
	}
	var outch chan ChangeRequest
	inch := theService.c
loop:
	for {
		select {
		case r := <-inch:
			if r.errno != 0 {
				ec.errno = r.errno
				break loop
			}
			inch = nil
			outch = cmdsToHandler
			outcr.Cmd = r.cmd
			outcr.EventType = r.eventType
			outcr.EventData = r.eventData
			outcr.Context = r.context
		case outch <- outcr:
			inch = theService.c
			outch = nil
		case c := <-changesFromHandler:
			err := theService.updateStatus(&c, &ec)
			if err != nil {
				ec.errno = uint32(windows.ERROR_EXCEPTION_IN_SERVICE)
				if err2, ok := err.(windows.Errno); ok {
					ec.errno = uint32(err2)
				}
				break loop
			}
			outcr.CurrentStatus = c
		case ec = <-exitFromHandler:
			break loop
		}
	}

	theService.updateStatus(&Status{State: Stopped}, &ec)

	return windows.NO_ERROR
}

// Run executes service name by calling appropriate handler function.
func Run(name string, handler Handler) error {
	initCallbacks.Do(func() {
		ctlHandlerCallback = windows.NewCallback(ctlHandler)
		serviceMainCallback = windows.NewCallback(serviceMain)
	})
	theService.name = name
	theService.handler = handler
	theService.c = make(chan ctlEvent)
	t := []windows.SERVICE_TABLE_ENTRY{
		{ServiceName: windows.StringToUTF16Ptr(theService.name), ServiceProc: serviceMainCallback},
		{ServiceName: nil, ServiceProc: 0},
	}
	return windows.StartServiceCtrlDispatcher(&t[0])
}

// StatusHandle returns service status handle. It is safe to call this function
// from inside the Handler.Execute because then it is guaranteed to be set.
func StatusHandle() windows.Handle {
	return theService.h
}

// DynamicStartReason returns the reason why the service was started. It is safe
// to call this function from inside the Handler.Execute because then it is
// guaranteed to be set.
func DynamicStartReason() (StartReason, error) {
	var allocReason *uint32
	err := windows.QueryServiceDynamicInformation(theService.h, windows.SERVICE_DYNAMIC_INFORMATION_LEVEL_START_REASON, unsafe.Pointer(&allocReason))
	if err != nil {
		return 0, err
	}
	reason := StartReason(*allocReason)
	windows.LocalFree(windows.Handle(unsafe.Pointer(allocReason)))
	return reason, nil
}
