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

package errorreporting

import (
	"errors"
	"strings"
	"testing"
	"time"

	"cloud.google.com/go/internal/testutil"
	gax "github.com/googleapis/gax-go"
	"golang.org/x/net/context"
	"google.golang.org/api/option"
	pb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1"
)

type fakeReportErrorsClient struct {
	req    *pb.ReportErrorEventRequest
	fail   bool
	doneCh chan struct{}
}

func (c *fakeReportErrorsClient) ReportErrorEvent(ctx context.Context, req *pb.ReportErrorEventRequest, _ ...gax.CallOption) (*pb.ReportErrorEventResponse, error) {
	defer close(c.doneCh)
	if c.fail {
		return nil, errors.New("request failed")
	}
	c.req = req
	return &pb.ReportErrorEventResponse{}, nil
}

func (c *fakeReportErrorsClient) Close() error {
	return nil
}

var defaultConfig = Config{
	ServiceName:    "myservice",
	ServiceVersion: "v1.0",
}

func newFakeReportErrorsClient() *fakeReportErrorsClient {
	c := &fakeReportErrorsClient{}
	c.doneCh = make(chan struct{})
	return c
}

func newTestClient(c *fakeReportErrorsClient, cfg Config) *Client {
	newClient = func(ctx context.Context, opts ...option.ClientOption) (client, error) {
		return c, nil
	}
	t, err := NewClient(context.Background(), testutil.ProjID(), cfg)
	if err != nil {
		panic(err)
	}
	return t
}

func commonChecks(t *testing.T, req *pb.ReportErrorEventRequest, fn string) {
	if req.Event.ServiceContext.Service != "myservice" {
		t.Errorf("error report didn't contain service name")
	}
	if req.Event.ServiceContext.Version != "v1.0" {
		t.Errorf("error report didn't contain version name")
	}
	if !strings.Contains(req.Event.Message, "error") {
		t.Errorf("error report didn't contain message")
	}
	if !strings.Contains(req.Event.Message, fn) {
		t.Errorf("error report didn't contain stack trace")
	}
	if got, want := req.Event.Context.User, "user"; got != want {
		t.Errorf("got %q, want %q", got, want)
	}
}

func TestReport(t *testing.T) {
	fc := newFakeReportErrorsClient()
	c := newTestClient(fc, defaultConfig)
	c.Report(Entry{Error: errors.New("error"), User: "user"})
	c.Flush()
	<-fc.doneCh
	r := fc.req
	if r == nil {
		t.Fatalf("got no error report, expected one")
	}
	commonChecks(t, r, "errorreporting.TestReport")
}

func TestReportSync(t *testing.T) {
	ctx := context.Background()
	fc := newFakeReportErrorsClient()
	c := newTestClient(fc, defaultConfig)
	if err := c.ReportSync(ctx, Entry{Error: errors.New("error"), User: "user"}); err != nil {
		t.Fatalf("cannot upload errors: %v", err)
	}

	<-fc.doneCh
	r := fc.req
	if r == nil {
		t.Fatalf("got no error report, expected one")
	}
	commonChecks(t, r, "errorreporting.TestReport")
}

func TestOnError(t *testing.T) {
	fc := newFakeReportErrorsClient()
	fc.fail = true
	cfg := defaultConfig
	errc := make(chan error, 1)
	cfg.OnError = func(err error) { errc <- err }
	c := newTestClient(fc, cfg)
	c.Report(Entry{Error: errors.New("error")})
	c.Flush()
	<-fc.doneCh
	select {
	case err := <-errc:
		if err == nil {
			t.Error("got nil, want error")
		}
	case <-time.After(5 * time.Second):
		t.Error("timeout")
	}
}

func TestChopStack(t *testing.T) {
	for _, test := range []struct {
		name     string
		in       []byte
		expected string
	}{
		{
			name: "Report",
			in: []byte(` goroutine 39 [running]:
runtime/debug.Stack()
	/gopath/runtime/debug/stack.go:24 +0x79
cloud.google.com/go/errorreporting.(*Client).logInternal()
	/gopath/cloud.google.com/go/errorreporting/errors.go:259 +0x18b
cloud.google.com/go/errorreporting.(*Client).Report()
	/gopath/cloud.google.com/go/errorreporting/errors.go:248 +0x4ed
cloud.google.com/go/errorreporting.TestReport()
	/gopath/cloud.google.com/go/errorreporting/errors_test.go:137 +0x2a1
testing.tRunner()
	/gopath/testing/testing.go:610 +0x81
created by testing.(*T).Run
	/gopath/testing/testing.go:646 +0x2ec
`),
			expected: ` goroutine 39 [running]:
cloud.google.com/go/errorreporting.TestReport()
	/gopath/cloud.google.com/go/errorreporting/errors_test.go:137 +0x2a1
testing.tRunner()
	/gopath/testing/testing.go:610 +0x81
created by testing.(*T).Run
	/gopath/testing/testing.go:646 +0x2ec
`,
		},
	} {
		out := chopStack(test.in)
		if out != test.expected {
			t.Errorf("case %q: chopStack(%q): got %q want %q", test.name, test.in, out, test.expected)
		}
	}
}
