package winrm

import (
	"bytes"
	"io"
	"regexp"
	"strconv"
	"testing"

	"github.com/dylanmei/winrmtest"
	"github.com/hashicorp/terraform/internal/communicator/remote"
	"github.com/hashicorp/terraform/internal/communicator/shared"
	"github.com/zclconf/go-cty/cty"
)

func newMockWinRMServer(t *testing.T) *winrmtest.Remote {
	wrm := winrmtest.NewRemote()

	wrm.CommandFunc(
		winrmtest.MatchText("echo foo"),
		func(out, err io.Writer) int {
			out.Write([]byte("foo"))
			return 0
		})

	wrm.CommandFunc(
		winrmtest.MatchPattern(`^echo c29tZXRoaW5n >> ".*"$`),
		func(out, err io.Writer) int {
			return 0
		})

	wrm.CommandFunc(
		winrmtest.MatchPattern(`^powershell.exe -EncodedCommand .*$`),
		func(out, err io.Writer) int {
			return 0
		})

	wrm.CommandFunc(
		winrmtest.MatchText("powershell"),
		func(out, err io.Writer) int {
			return 0
		})

	return wrm
}

func TestStart(t *testing.T) {
	wrm := newMockWinRMServer(t)
	defer wrm.Close()

	v := cty.ObjectVal(map[string]cty.Value{
		"type":     cty.StringVal("winrm"),
		"user":     cty.StringVal("user"),
		"password": cty.StringVal("pass"),
		"host":     cty.StringVal(wrm.Host),
		"port":     cty.StringVal(strconv.Itoa(wrm.Port)),
		"timeout":  cty.StringVal("30s"),
	})

	c, err := New(v)
	if err != nil {
		t.Fatalf("error creating communicator: %s", err)
	}

	var cmd remote.Cmd
	stdout := new(bytes.Buffer)
	cmd.Command = "echo foo"
	cmd.Stdout = stdout

	err = c.Start(&cmd)
	if err != nil {
		t.Fatalf("error executing remote command: %s", err)
	}
	cmd.Wait()

	if stdout.String() != "foo" {
		t.Fatalf("bad command response: expected %q, got %q", "foo", stdout.String())
	}
}

func TestUpload(t *testing.T) {
	wrm := newMockWinRMServer(t)
	defer wrm.Close()
	v := cty.ObjectVal(map[string]cty.Value{
		"type":     cty.StringVal("winrm"),
		"user":     cty.StringVal("user"),
		"password": cty.StringVal("pass"),
		"host":     cty.StringVal(wrm.Host),
		"port":     cty.StringVal(strconv.Itoa(wrm.Port)),
		"timeout":  cty.StringVal("30s"),
	})

	c, err := New(v)
	if err != nil {
		t.Fatalf("error creating communicator: %s", err)
	}

	err = c.Connect(nil)
	if err != nil {
		t.Fatalf("error connecting communicator: %s", err)
	}
	defer c.Disconnect()

	err = c.Upload("C:/Temp/terraform.cmd", bytes.NewReader([]byte("something")))
	if err != nil {
		t.Fatalf("error uploading file: %s", err)
	}
}

func TestScriptPath(t *testing.T) {
	cases := []struct {
		Input   string
		Pattern string
	}{
		{
			"/tmp/script.sh",
			`^/tmp/script\.sh$`,
		},
		{
			"/tmp/script_%RAND%.sh",
			`^/tmp/script_(\d+)\.sh$`,
		},
	}

	for _, tc := range cases {
		v := cty.ObjectVal(map[string]cty.Value{
			"host":        cty.StringVal(""),
			"type":        cty.StringVal("winrm"),
			"script_path": cty.StringVal(tc.Input),
		})

		comm, err := New(v)
		if err != nil {
			t.Fatalf("err: %s", err)
		}
		output := comm.ScriptPath()

		match, err := regexp.Match(tc.Pattern, []byte(output))
		if err != nil {
			t.Fatalf("bad: %s\n\nerr: %s", tc.Input, err)
		}
		if !match {
			t.Fatalf("bad: %s\n\n%s", tc.Input, output)
		}
	}
}

func TestNoTransportDecorator(t *testing.T) {
	wrm := newMockWinRMServer(t)
	defer wrm.Close()
	v := cty.ObjectVal(map[string]cty.Value{
		"type":     cty.StringVal("winrm"),
		"user":     cty.StringVal("user"),
		"password": cty.StringVal("pass"),
		"host":     cty.StringVal(wrm.Host),
		"port":     cty.StringVal(strconv.Itoa(wrm.Port)),
		"timeout":  cty.StringVal("30s"),
	})

	c, err := New(v)
	if err != nil {
		t.Fatalf("error creating communicator: %s", err)
	}

	err = c.Connect(nil)
	if err != nil {
		t.Fatalf("error connecting communicator: %s", err)
	}
	defer c.Disconnect()

	if c.client.TransportDecorator != nil {
		t.Fatal("bad TransportDecorator: expected nil, got non-nil")
	}
}

func TestTransportDecorator(t *testing.T) {
	wrm := newMockWinRMServer(t)
	defer wrm.Close()

	v := cty.ObjectVal(map[string]cty.Value{
		"type":     cty.StringVal("winrm"),
		"user":     cty.StringVal("user"),
		"password": cty.StringVal("pass"),
		"host":     cty.StringVal(wrm.Host),
		"port":     cty.StringVal(strconv.Itoa(wrm.Port)),
		"use_ntlm": cty.StringVal("true"),
		"timeout":  cty.StringVal("30s"),
	})

	c, err := New(v)
	if err != nil {
		t.Fatalf("error creating communicator: %s", err)
	}

	err = c.Connect(nil)
	if err != nil {
		t.Fatalf("error connecting communicator: %s", err)
	}
	defer c.Disconnect()

	if c.client.TransportDecorator == nil {
		t.Fatal("bad TransportDecorator: expected non-nil, got nil")
	}
}

func TestScriptPath_randSeed(t *testing.T) {
	// Pre GH-4186 fix, this value was the deterministic start the pseudorandom
	// chain of unseeded math/rand values for Int31().
	staticSeedPath := "C:/Temp/terraform_1298498081.cmd"
	c, err := New(cty.NullVal(shared.ConnectionBlockSupersetSchema.ImpliedType()))
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	path := c.ScriptPath()
	if path == staticSeedPath {
		t.Fatalf("rand not seeded! got: %s", path)
	}
}
