// 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 mgr_test

import (
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"syscall"
	"testing"
	"time"

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

func TestOpenLanManServer(t *testing.T) {
	m, err := mgr.Connect()
	if err != nil {
		if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED {
			t.Skip("Skipping test: we don't have rights to manage services.")
		}
		t.Fatalf("SCM connection failed: %s", err)
	}
	defer m.Disconnect()

	s, err := m.OpenService("LanmanServer")
	if err != nil {
		t.Fatalf("OpenService(lanmanserver) failed: %s", err)
	}
	defer s.Close()

	_, err = s.Config()
	if err != nil {
		t.Fatalf("Config failed: %s", err)
	}
}

func install(t *testing.T, m *mgr.Mgr, name, exepath string, c mgr.Config) {
	// Sometimes it takes a while for the service to get
	// removed after previous test run.
	for i := 0; ; i++ {
		s, err := m.OpenService(name)
		if err != nil {
			break
		}
		s.Close()

		if i > 10 {
			t.Fatalf("service %s already exists", name)
		}
		time.Sleep(300 * time.Millisecond)
	}

	s, err := m.CreateService(name, exepath, c)
	if err != nil {
		t.Fatalf("CreateService(%s) failed: %v", name, err)
	}
	defer s.Close()
}

func depString(d []string) string {
	if len(d) == 0 {
		return ""
	}
	for i := range d {
		d[i] = strings.ToLower(d[i])
	}
	ss := sort.StringSlice(d)
	ss.Sort()
	return strings.Join([]string(ss), " ")
}

func testConfig(t *testing.T, s *mgr.Service, should mgr.Config) mgr.Config {
	is, err := s.Config()
	if err != nil {
		t.Fatalf("Config failed: %s", err)
	}
	if should.DelayedAutoStart != is.DelayedAutoStart {
		t.Fatalf("config mismatch: DelayedAutoStart is %v, but should have %v", is.DelayedAutoStart, should.DelayedAutoStart)
	}
	if should.DisplayName != is.DisplayName {
		t.Fatalf("config mismatch: DisplayName is %q, but should have %q", is.DisplayName, should.DisplayName)
	}
	if should.StartType != is.StartType {
		t.Fatalf("config mismatch: StartType is %v, but should have %v", is.StartType, should.StartType)
	}
	if should.Description != is.Description {
		t.Fatalf("config mismatch: Description is %q, but should have %q", is.Description, should.Description)
	}
	if depString(should.Dependencies) != depString(is.Dependencies) {
		t.Fatalf("config mismatch: Dependencies is %v, but should have %v", is.Dependencies, should.Dependencies)
	}
	return is
}

func testRecoveryActions(t *testing.T, s *mgr.Service, should []mgr.RecoveryAction) {
	is, err := s.RecoveryActions()
	if err != nil {
		t.Fatalf("RecoveryActions failed: %s", err)
	}
	if len(should) != len(is) {
		t.Errorf("recovery action mismatch: contains %v actions, but should have %v", len(is), len(should))
	}
	for i, _ := range is {
		if should[i].Type != is[i].Type {
			t.Errorf("recovery action mismatch: Type is %v, but should have %v", is[i].Type, should[i].Type)
		}
		if should[i].Delay != is[i].Delay {
			t.Errorf("recovery action mismatch: Delay is %v, but should have %v", is[i].Delay, should[i].Delay)
		}
	}
}

func testResetPeriod(t *testing.T, s *mgr.Service, should uint32) {
	is, err := s.ResetPeriod()
	if err != nil {
		t.Fatalf("ResetPeriod failed: %s", err)
	}
	if should != is {
		t.Errorf("reset period mismatch: reset period is %v, but should have %v", is, should)
	}
}

func testSetRecoveryActions(t *testing.T, s *mgr.Service) {
	r := []mgr.RecoveryAction{
		mgr.RecoveryAction{
			Type:  mgr.NoAction,
			Delay: 60000 * time.Millisecond,
		},
		mgr.RecoveryAction{
			Type:  mgr.ServiceRestart,
			Delay: 4 * time.Minute,
		},
		mgr.RecoveryAction{
			Type:  mgr.ServiceRestart,
			Delay: time.Minute,
		},
		mgr.RecoveryAction{
			Type:  mgr.RunCommand,
			Delay: 4000 * time.Millisecond,
		},
	}

	// 4 recovery actions with reset period
	err := s.SetRecoveryActions(r, uint32(10000))
	if err != nil {
		t.Fatalf("SetRecoveryActions failed: %v", err)
	}
	testRecoveryActions(t, s, r)
	testResetPeriod(t, s, uint32(10000))

	// Infinite reset period
	err = s.SetRecoveryActions(r, syscall.INFINITE)
	if err != nil {
		t.Fatalf("SetRecoveryActions failed: %v", err)
	}
	testRecoveryActions(t, s, r)
	testResetPeriod(t, s, syscall.INFINITE)

	// nil recovery actions
	err = s.SetRecoveryActions(nil, 0)
	if err.Error() != "recoveryActions cannot be nil" {
		t.Fatalf("SetRecoveryActions failed with unexpected error message of %q", err)
	}

	// Delete all recovery actions and reset period
	err = s.ResetRecoveryActions()
	if err != nil {
		t.Fatalf("ResetRecoveryActions failed: %v", err)
	}
	testRecoveryActions(t, s, nil)
	testResetPeriod(t, s, 0)
}

func testRebootMessage(t *testing.T, s *mgr.Service, should string) {
	err := s.SetRebootMessage(should)
	if err != nil {
		t.Fatalf("SetRebootMessage failed: %v", err)
	}
	is, err := s.RebootMessage()
	if err != nil {
		t.Fatalf("RebootMessage failed: %v", err)
	}
	if should != is {
		t.Errorf("reboot message mismatch: message is %q, but should have %q", is, should)
	}
}

func testRecoveryCommand(t *testing.T, s *mgr.Service, should string) {
	err := s.SetRecoveryCommand(should)
	if err != nil {
		t.Fatalf("SetRecoveryCommand failed: %v", err)
	}
	is, err := s.RecoveryCommand()
	if err != nil {
		t.Fatalf("RecoveryCommand failed: %v", err)
	}
	if should != is {
		t.Errorf("recovery command mismatch: command is %q, but should have %q", is, should)
	}
}

func remove(t *testing.T, s *mgr.Service) {
	err := s.Delete()
	if err != nil {
		t.Fatalf("Delete failed: %s", err)
	}
}

func TestMyService(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode - it modifies system services")
	}

	const name = "mymgrservice"

	m, err := mgr.Connect()
	if err != nil {
		if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED {
			t.Skip("Skipping test: we don't have rights to manage services.")
		}
		t.Fatalf("SCM connection failed: %s", err)
	}
	defer m.Disconnect()

	c := mgr.Config{
		StartType:    mgr.StartDisabled,
		DisplayName:  "my service",
		Description:  "my service is just a test",
		Dependencies: []string{"LanmanServer", "W32Time"},
	}

	exename := os.Args[0]
	exepath, err := filepath.Abs(exename)
	if err != nil {
		t.Fatalf("filepath.Abs(%s) failed: %s", exename, err)
	}

	install(t, m, name, exepath, c)

	s, err := m.OpenService(name)
	if err != nil {
		t.Fatalf("service %s is not installed", name)
	}
	defer s.Close()

	c.BinaryPathName = exepath
	c = testConfig(t, s, c)

	c.StartType = mgr.StartManual
	err = s.UpdateConfig(c)
	if err != nil {
		t.Fatalf("UpdateConfig failed: %v", err)
	}

	testConfig(t, s, c)

	c.StartType = mgr.StartAutomatic
	c.DelayedAutoStart = true
	err = s.UpdateConfig(c)
	if err != nil {
		t.Fatalf("UpdateConfig failed: %v", err)
	}

	testConfig(t, s, c)

	svcnames, err := m.ListServices()
	if err != nil {
		t.Fatalf("ListServices failed: %v", err)
	}
	var myserviceIsInstalled bool
	for _, sn := range svcnames {
		if sn == name {
			myserviceIsInstalled = true
			break
		}
	}
	if !myserviceIsInstalled {
		t.Errorf("ListServices failed to find %q service", name)
	}

	testSetRecoveryActions(t, s)
	testRebootMessage(t, s, fmt.Sprintf("%s failed", name))
	testRebootMessage(t, s, "") // delete reboot message
	testRecoveryCommand(t, s, fmt.Sprintf("sc query %s", name))
	testRecoveryCommand(t, s, "") // delete recovery command

	remove(t, s)
}
