// Copyright 2016 The etcd Authors
//
// Licensed 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.

package e2e

import (
	"fmt"
	"math/rand"
	"strings"
	"testing"

	"github.com/coreos/etcd/pkg/testutil"
)

func TestV2CurlNoTLS(t *testing.T)      { testCurlPutGet(t, &configNoTLS) }
func TestV2CurlAutoTLS(t *testing.T)    { testCurlPutGet(t, &configAutoTLS) }
func TestV2CurlAllTLS(t *testing.T)     { testCurlPutGet(t, &configTLS) }
func TestV2CurlPeerTLS(t *testing.T)    { testCurlPutGet(t, &configPeerTLS) }
func TestV2CurlClientTLS(t *testing.T)  { testCurlPutGet(t, &configClientTLS) }
func TestV2CurlClientBoth(t *testing.T) { testCurlPutGet(t, &configClientBoth) }
func testCurlPutGet(t *testing.T, cfg *etcdProcessClusterConfig) {
	defer testutil.AfterTest(t)

	// test doesn't use quorum gets, so ensure there are no followers to avoid
	// stale reads that will break the test
	cfg = configStandalone(*cfg)

	epc, err := newEtcdProcessCluster(cfg)
	if err != nil {
		t.Fatalf("could not start etcd process cluster (%v)", err)
	}
	defer func() {
		if err := epc.Close(); err != nil {
			t.Fatalf("error closing etcd processes (%v)", err)
		}
	}()

	var (
		expectPut = `{"action":"set","node":{"key":"/foo","value":"bar","`
		expectGet = `{"action":"get","node":{"key":"/foo","value":"bar","`
	)
	if err := cURLPut(epc, cURLReq{endpoint: "/v2/keys/foo", value: "bar", expected: expectPut}); err != nil {
		t.Fatalf("failed put with curl (%v)", err)
	}
	if err := cURLGet(epc, cURLReq{endpoint: "/v2/keys/foo", expected: expectGet}); err != nil {
		t.Fatalf("failed get with curl (%v)", err)
	}
	if cfg.clientTLS == clientTLSAndNonTLS {
		if err := cURLGet(epc, cURLReq{endpoint: "/v2/keys/foo", expected: expectGet, isTLS: true}); err != nil {
			t.Fatalf("failed get with curl (%v)", err)
		}
	}
}

func TestV2CurlIssue5182(t *testing.T) {
	defer testutil.AfterTest(t)

	epc := setupEtcdctlTest(t, &configNoTLS, false)
	defer func() {
		if err := epc.Close(); err != nil {
			t.Fatalf("error closing etcd processes (%v)", err)
		}
	}()

	expectPut := `{"action":"set","node":{"key":"/foo","value":"bar","`
	if err := cURLPut(epc, cURLReq{endpoint: "/v2/keys/foo", value: "bar", expected: expectPut}); err != nil {
		t.Fatal(err)
	}

	expectUserAdd := `{"user":"foo","roles":null}`
	if err := cURLPut(epc, cURLReq{endpoint: "/v2/auth/users/foo", value: `{"user":"foo", "password":"pass"}`, expected: expectUserAdd}); err != nil {
		t.Fatal(err)
	}
	expectRoleAdd := `{"role":"foo","permissions":{"kv":{"read":["/foo/*"],"write":null}}`
	if err := cURLPut(epc, cURLReq{endpoint: "/v2/auth/roles/foo", value: `{"role":"foo", "permissions": {"kv": {"read": ["/foo/*"]}}}`, expected: expectRoleAdd}); err != nil {
		t.Fatal(err)
	}
	expectUserUpdate := `{"user":"foo","roles":["foo"]}`
	if err := cURLPut(epc, cURLReq{endpoint: "/v2/auth/users/foo", value: `{"user": "foo", "grant": ["foo"]}`, expected: expectUserUpdate}); err != nil {
		t.Fatal(err)
	}

	if err := etcdctlUserAdd(epc, "root", "a"); err != nil {
		t.Fatal(err)
	}
	if err := etcdctlAuthEnable(epc); err != nil {
		t.Fatal(err)
	}

	if err := cURLGet(epc, cURLReq{endpoint: "/v2/keys/foo/", username: "root", password: "a", expected: "bar"}); err != nil {
		t.Fatal(err)
	}
	if err := cURLGet(epc, cURLReq{endpoint: "/v2/keys/foo/", username: "foo", password: "pass", expected: "bar"}); err != nil {
		t.Fatal(err)
	}
	if err := cURLGet(epc, cURLReq{endpoint: "/v2/keys/foo/", username: "foo", password: "", expected: "bar"}); err != nil {
		if !strings.Contains(err.Error(), `The request requires user authentication`) {
			t.Fatalf("expected 'The request requires user authentication' error, got %v", err)
		}
	} else {
		t.Fatalf("expected 'The request requires user authentication' error")
	}
}

type cURLReq struct {
	username string
	password string

	isTLS   bool
	timeout int

	endpoint string

	value    string
	expected string
	header   string

	metricsURLScheme string

	ciphers string
}

// cURLPrefixArgs builds the beginning of a curl command for a given key
// addressed to a random URL in the given cluster.
func cURLPrefixArgs(clus *etcdProcessCluster, method string, req cURLReq) []string {
	var (
		cmdArgs = []string{"curl"}
		acurl   = clus.procs[rand.Intn(clus.cfg.clusterSize)].Config().acurl
	)
	if req.metricsURLScheme != "https" {
		if req.isTLS {
			if clus.cfg.clientTLS != clientTLSAndNonTLS {
				panic("should not use cURLPrefixArgsUseTLS when serving only TLS or non-TLS")
			}
			cmdArgs = append(cmdArgs, "--cacert", caPath, "--cert", certPath, "--key", privateKeyPath)
			acurl = toTLS(clus.procs[rand.Intn(clus.cfg.clusterSize)].Config().acurl)
		} else if clus.cfg.clientTLS == clientTLS {
			cmdArgs = append(cmdArgs, "--cacert", caPath, "--cert", certPath, "--key", privateKeyPath)
		}
	}
	if req.metricsURLScheme != "" {
		acurl = clus.procs[rand.Intn(clus.cfg.clusterSize)].EndpointsMetrics()[0]
	}
	ep := acurl + req.endpoint

	if req.username != "" || req.password != "" {
		cmdArgs = append(cmdArgs, "-L", "-u", fmt.Sprintf("%s:%s", req.username, req.password), ep)
	} else {
		cmdArgs = append(cmdArgs, "-L", ep)
	}
	if req.timeout != 0 {
		cmdArgs = append(cmdArgs, "-m", fmt.Sprintf("%d", req.timeout))
	}

	if req.header != "" {
		cmdArgs = append(cmdArgs, "-H", req.header)
	}

	if req.ciphers != "" {
		cmdArgs = append(cmdArgs, "--ciphers", req.ciphers)
	}

	switch method {
	case "POST", "PUT":
		dt := req.value
		if !strings.HasPrefix(dt, "{") { // for non-JSON value
			dt = "value=" + dt
		}
		cmdArgs = append(cmdArgs, "-X", method, "-d", dt)
	}
	return cmdArgs
}

func cURLPost(clus *etcdProcessCluster, req cURLReq) error {
	return spawnWithExpect(cURLPrefixArgs(clus, "POST", req), req.expected)
}

func cURLPut(clus *etcdProcessCluster, req cURLReq) error {
	return spawnWithExpect(cURLPrefixArgs(clus, "PUT", req), req.expected)
}

func cURLGet(clus *etcdProcessCluster, req cURLReq) error {
	return spawnWithExpect(cURLPrefixArgs(clus, "GET", req), req.expected)
}
