// Copyright 2018 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.

package acme

import (
	"context"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"reflect"
	"strings"
	"testing"
	"time"
)

func TestDefaultBackoff(t *testing.T) {
	tt := []struct {
		nretry     int
		retryAfter string        // Retry-After header
		out        time.Duration // expected min; max = min + jitter
	}{
		{-1, "", time.Second},       // verify the lower bound is 1
		{0, "", time.Second},        // verify the lower bound is 1
		{100, "", 10 * time.Second}, // verify the ceiling
		{1, "3600", time.Hour},      // verify the header value is used
		{1, "", 1 * time.Second},
		{2, "", 2 * time.Second},
		{3, "", 4 * time.Second},
		{4, "", 8 * time.Second},
	}
	for i, test := range tt {
		r := httptest.NewRequest("GET", "/", nil)
		resp := &http.Response{Header: http.Header{}}
		if test.retryAfter != "" {
			resp.Header.Set("Retry-After", test.retryAfter)
		}
		d := defaultBackoff(test.nretry, r, resp)
		max := test.out + time.Second // + max jitter
		if d < test.out || max < d {
			t.Errorf("%d: defaultBackoff(%v) = %v; want between %v and %v", i, test.nretry, d, test.out, max)
		}
	}
}

func TestErrorResponse(t *testing.T) {
	s := `{
		"status": 400,
		"type": "urn:acme:error:xxx",
		"detail": "text"
	}`
	res := &http.Response{
		StatusCode: 400,
		Status:     "400 Bad Request",
		Body:       ioutil.NopCloser(strings.NewReader(s)),
		Header:     http.Header{"X-Foo": {"bar"}},
	}
	err := responseError(res)
	v, ok := err.(*Error)
	if !ok {
		t.Fatalf("err = %+v (%T); want *Error type", err, err)
	}
	if v.StatusCode != 400 {
		t.Errorf("v.StatusCode = %v; want 400", v.StatusCode)
	}
	if v.ProblemType != "urn:acme:error:xxx" {
		t.Errorf("v.ProblemType = %q; want urn:acme:error:xxx", v.ProblemType)
	}
	if v.Detail != "text" {
		t.Errorf("v.Detail = %q; want text", v.Detail)
	}
	if !reflect.DeepEqual(v.Header, res.Header) {
		t.Errorf("v.Header = %+v; want %+v", v.Header, res.Header)
	}
}

func TestPostWithRetries(t *testing.T) {
	var count int
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		count++
		w.Header().Set("Replay-Nonce", fmt.Sprintf("nonce%d", count))
		if r.Method == "HEAD" {
			// We expect the client to do 2 head requests to fetch
			// nonces, one to start and another after getting badNonce
			return
		}

		head, err := decodeJWSHead(r.Body)
		switch {
		case err != nil:
			t.Errorf("decodeJWSHead: %v", err)
		case head.Nonce == "":
			t.Error("head.Nonce is empty")
		case head.Nonce == "nonce1":
			// Return a badNonce error to force the call to retry.
			w.Header().Set("Retry-After", "0")
			w.WriteHeader(http.StatusBadRequest)
			w.Write([]byte(`{"type":"urn:ietf:params:acme:error:badNonce"}`))
			return
		}
		// Make client.Authorize happy; we're not testing its result.
		w.WriteHeader(http.StatusCreated)
		w.Write([]byte(`{"status":"valid"}`))
	}))
	defer ts.Close()

	client := &Client{
		Key:          testKey,
		DirectoryURL: ts.URL,
		dir:          &Directory{AuthzURL: ts.URL},
	}
	// This call will fail with badNonce, causing a retry
	if _, err := client.Authorize(context.Background(), "example.com"); err != nil {
		t.Errorf("client.Authorize 1: %v", err)
	}
	if count != 3 {
		t.Errorf("total requests count: %d; want 3", count)
	}
}

func TestRetryErrorType(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Replay-Nonce", "nonce")
		w.WriteHeader(http.StatusTooManyRequests)
		w.Write([]byte(`{"type":"rateLimited"}`))
	}))
	defer ts.Close()

	client := &Client{
		Key: testKey,
		RetryBackoff: func(n int, r *http.Request, res *http.Response) time.Duration {
			// Do no retries.
			return 0
		},
		dir: &Directory{AuthzURL: ts.URL},
	}

	t.Run("post", func(t *testing.T) {
		testRetryErrorType(t, func() error {
			_, err := client.Authorize(context.Background(), "example.com")
			return err
		})
	})
	t.Run("get", func(t *testing.T) {
		testRetryErrorType(t, func() error {
			_, err := client.GetAuthorization(context.Background(), ts.URL)
			return err
		})
	})
}

func testRetryErrorType(t *testing.T, callClient func() error) {
	t.Helper()
	err := callClient()
	if err == nil {
		t.Fatal("client.Authorize returned nil error")
	}
	acmeErr, ok := err.(*Error)
	if !ok {
		t.Fatalf("err is %v (%T); want *Error", err, err)
	}
	if acmeErr.StatusCode != http.StatusTooManyRequests {
		t.Errorf("acmeErr.StatusCode = %d; want %d", acmeErr.StatusCode, http.StatusTooManyRequests)
	}
	if acmeErr.ProblemType != "rateLimited" {
		t.Errorf("acmeErr.ProblemType = %q; want 'rateLimited'", acmeErr.ProblemType)
	}
}

func TestRetryBackoffArgs(t *testing.T) {
	const resCode = http.StatusInternalServerError
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Replay-Nonce", "test-nonce")
		w.WriteHeader(resCode)
	}))
	defer ts.Close()

	// Canceled in backoff.
	ctx, cancel := context.WithCancel(context.Background())

	var nretry int
	backoff := func(n int, r *http.Request, res *http.Response) time.Duration {
		nretry++
		if n != nretry {
			t.Errorf("n = %d; want %d", n, nretry)
		}
		if nretry == 3 {
			cancel()
		}

		if r == nil {
			t.Error("r is nil")
		}
		if res.StatusCode != resCode {
			t.Errorf("res.StatusCode = %d; want %d", res.StatusCode, resCode)
		}
		return time.Millisecond
	}

	client := &Client{
		Key:          testKey,
		RetryBackoff: backoff,
		dir:          &Directory{AuthzURL: ts.URL},
	}
	if _, err := client.Authorize(ctx, "example.com"); err == nil {
		t.Error("err is nil")
	}
	if nretry != 3 {
		t.Errorf("nretry = %d; want 3", nretry)
	}
}

func TestUserAgent(t *testing.T) {
	for _, custom := range []string{"", "CUSTOM_UA"} {
		ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			t.Log(r.UserAgent())
			if s := "golang.org/x/crypto/acme"; !strings.Contains(r.UserAgent(), s) {
				t.Errorf("expected User-Agent to contain %q, got %q", s, r.UserAgent())
			}
			if !strings.Contains(r.UserAgent(), custom) {
				t.Errorf("expected User-Agent to contain %q, got %q", custom, r.UserAgent())
			}

			w.WriteHeader(http.StatusOK)
			w.Write([]byte(`{"newOrder": "sure"}`))
		}))
		defer ts.Close()

		client := &Client{
			Key:          testKey,
			DirectoryURL: ts.URL,
			UserAgent:    custom,
		}
		if _, err := client.Discover(context.Background()); err != nil {
			t.Errorf("client.Discover: %v", err)
		}
	}
}

func TestAccountKidLoop(t *testing.T) {
	// if Client.postNoRetry is called with a nil key argument
	// then Client.Key must be set, otherwise we fall into an
	// infinite loop (which also causes a deadlock).
	client := &Client{dir: &Directory{OrderURL: ":)"}}
	_, _, err := client.postNoRetry(context.Background(), nil, "", nil)
	if err == nil {
		t.Fatal("Client.postNoRetry didn't fail with a nil key")
	}
	expected := "acme: Client.Key must be populated to make POST requests"
	if err.Error() != expected {
		t.Fatalf("Unexpected error returned: wanted %q, got %q", expected, err.Error())
	}
}
