// Copyright 2012 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package runtime

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/golang/protobuf/proto"

	"google.golang.org/appengine/internal/aetesting"
	pb "google.golang.org/appengine/internal/system"
)

func TestRunInBackgroundSendFirst(t *testing.T) { testRunInBackground(t, true) }
func TestRunInBackgroundRecvFirst(t *testing.T) { testRunInBackground(t, false) }

func testRunInBackground(t *testing.T, sendFirst bool) {
	srv := httptest.NewServer(nil)
	defer srv.Close()

	const id = "f00bar"
	sendWait, recvWait := make(chan bool), make(chan bool)
	sbr := make(chan bool) // strobed when system.StartBackgroundRequest has started

	calls := 0
	c := aetesting.FakeSingleContext(t, "system", "StartBackgroundRequest", func(req *pb.StartBackgroundRequestRequest, res *pb.StartBackgroundRequestResponse) error {
		calls++
		if calls > 1 {
			t.Errorf("Too many calls to system.StartBackgroundRequest")
		}
		sbr <- true
		res.RequestId = proto.String(id)
		<-sendWait
		return nil
	})

	var c2 context.Context // a fake
	newContext = func(*http.Request) context.Context {
		return c2
	}

	var fRun int
	f := func(c3 context.Context) {
		fRun++
		if c3 != c2 {
			t.Errorf("f got a different context than expected")
		}
	}

	ribErrc := make(chan error)
	go func() {
		ribErrc <- RunInBackground(c, f)
	}()

	brErrc := make(chan error)
	go func() {
		<-sbr
		req, err := http.NewRequest("GET", srv.URL+"/_ah/background", nil)
		if err != nil {
			brErrc <- fmt.Errorf("http.NewRequest: %v", err)
			return
		}
		req.Header.Set("X-AppEngine-BackgroundRequest", id)
		client := &http.Client{
			Transport: &http.Transport{
				Proxy: http.ProxyFromEnvironment,
			},
		}

		<-recvWait
		_, err = client.Do(req)
		brErrc <- err
	}()

	// Send and receive are both waiting at this point.
	waits := [2]chan bool{sendWait, recvWait}
	if !sendFirst {
		waits[0], waits[1] = waits[1], waits[0]
	}
	waits[0] <- true
	time.Sleep(100 * time.Millisecond)
	waits[1] <- true

	if err := <-ribErrc; err != nil {
		t.Fatalf("RunInBackground: %v", err)
	}
	if err := <-brErrc; err != nil {
		t.Fatalf("background request: %v", err)
	}

	if fRun != 1 {
		t.Errorf("Got %d runs of f, want 1", fRun)
	}
}
