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

// +build go1.8

package main_test

import (
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"strings"
	"testing"
	"time"

	"cloud.google.com/go/internal/testutil"
	"cloud.google.com/go/storage"
	"golang.org/x/net/context"
	"golang.org/x/oauth2"
	"google.golang.org/api/option"
)

const initial = "initial state"

func TestIntegration_HTTPR(t *testing.T) {
	if testing.Short() {
		t.Skip("Integration tests skipped in short mode")
	}
	if testutil.ProjID() == "" {
		t.Fatal("set GCLOUD_TESTS_GOLANG_PROJECT_ID and GCLOUD_TESTS_GOLANG_KEY")
	}
	// Get a unique temporary filename.
	f, err := ioutil.TempFile("", "httpreplay")
	if err != nil {
		t.Fatal(err)
	}
	replayFilename := f.Name()
	if err := f.Close(); err != nil {
		t.Fatal(err)
	}
	defer os.Remove(replayFilename)

	if err := exec.Command("go", "build").Run(); err != nil {
		t.Fatalf("running 'go build': %v", err)
	}
	defer os.Remove("./httpr")
	want := runRecord(t, replayFilename)
	got := runReplay(t, replayFilename)
	if got != want {
		t.Fatalf("got %q, want %q", got, want)
	}
}

func runRecord(t *testing.T, filename string) string {
	cmd, tr, cport, err := start("-record", filename)
	if err != nil {
		t.Fatal(err)
	}
	defer stop(t, cmd)

	ctx := context.Background()
	hc := &http.Client{
		Transport: &oauth2.Transport{
			Base:   tr,
			Source: testutil.TokenSource(ctx, storage.ScopeFullControl),
		},
	}
	res, err := http.Post(
		fmt.Sprintf("http://localhost:%s/initial", cport),
		"text/plain",
		strings.NewReader(initial))
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != 200 {
		t.Fatalf("from POST: %s", res.Status)
	}
	info, err := getBucketInfo(ctx, hc)
	if err != nil {
		t.Fatal(err)
	}
	return info
}

func runReplay(t *testing.T, filename string) string {
	cmd, tr, cport, err := start("-replay", filename)
	if err != nil {
		t.Fatal(err)
	}
	defer stop(t, cmd)

	hc := &http.Client{Transport: tr}
	res, err := http.Get(fmt.Sprintf("http://localhost:%s/initial", cport))
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != 200 {
		t.Fatalf("from GET: %s", res.Status)
	}
	bytes, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		t.Fatal(err)
	}
	if got, want := string(bytes), initial; got != want {
		t.Errorf("initial: got %q, want %q", got, want)
	}
	info, err := getBucketInfo(context.Background(), hc)
	if err != nil {
		t.Fatal(err)
	}
	return info
}

// Start the proxy binary and wait for it to come up.
// Return a transport that talks to the proxy, as well as the control port.
// modeFlag must be either "-record" or "-replay".
func start(modeFlag, filename string) (*exec.Cmd, *http.Transport, string, error) {
	pport, err := pickPort()
	if err != nil {
		return nil, nil, "", err
	}
	cport, err := pickPort()
	if err != nil {
		return nil, nil, "", err
	}
	cmd := exec.Command("./httpr", "-port", pport, "-control-port", cport, modeFlag, filename, "-debug-headers")
	if err := cmd.Start(); err != nil {
		return nil, nil, "", err
	}
	// Wait for the server to come up.
	serverUp := false
	for i := 0; i < 10; i++ {
		if conn, err := net.Dial("tcp", "localhost:"+cport); err == nil {
			conn.Close()
			serverUp = true
			break
		}
		time.Sleep(time.Second)
	}
	if !serverUp {
		return nil, nil, "", errors.New("server never came up")
	}
	tr, err := proxyTransport(pport, cport)
	if err != nil {
		return nil, nil, "", err
	}
	return cmd, tr, cport, nil
}

func stop(t *testing.T, cmd *exec.Cmd) {
	if err := cmd.Process.Signal(os.Interrupt); err != nil {
		t.Fatal(err)
	}
}

// pickPort picks an unused port.
func pickPort() (string, error) {
	l, err := net.Listen("tcp", ":0")
	if err != nil {
		return "", err
	}
	addr := l.Addr().String()
	_, port, err := net.SplitHostPort(addr)
	if err != nil {
		return "", err
	}
	l.Close()
	return port, nil
}

func proxyTransport(pport, cport string) (*http.Transport, error) {
	caCert, err := getBody(fmt.Sprintf("http://localhost:%s/authority.cer", cport))
	if err != nil {
		return nil, err
	}
	caCertPool := x509.NewCertPool()
	if !caCertPool.AppendCertsFromPEM([]byte(caCert)) {
		return nil, errors.New("bad CA Cert")
	}
	return &http.Transport{
		Proxy:           http.ProxyURL(&url.URL{Host: "localhost:" + pport}),
		TLSClientConfig: &tls.Config{RootCAs: caCertPool},
	}, nil
}

func getBucketInfo(ctx context.Context, hc *http.Client) (string, error) {
	client, err := storage.NewClient(ctx, option.WithHTTPClient(hc))
	if err != nil {
		return "", err
	}
	defer client.Close()
	b := client.Bucket(testutil.ProjID())
	attrs, err := b.Attrs(ctx)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("name:%s reqpays:%v location:%s sclass:%s",
		attrs.Name, attrs.RequesterPays, attrs.Location, attrs.StorageClass), nil
}

func getBody(url string) ([]byte, error) {
	res, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	if res.StatusCode != 200 {
		return nil, fmt.Errorf("response: %s", res.Status)
	}
	defer res.Body.Close()
	return ioutil.ReadAll(res.Body)
}
