// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 (
	"bytes"
	"errors"
	"log"
	"strings"
	"testing"

	gax "github.com/googleapis/gax-go"

	"golang.org/x/net/context"
	"google.golang.org/api/option"
	erpb "google.golang.org/genproto/googleapis/devtools/clouderrorreporting/v1beta1"
)

const testProjectID = "testproject"

type fakeReportErrorsClient struct {
	req  *erpb.ReportErrorEventRequest
	fail bool
}

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

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

func newTestClient(c *fakeReportErrorsClient) *Client {
	newApiInterface = func(ctx context.Context, opts ...option.ClientOption) (apiInterface, error) {
		return c, nil
	}
	t, err := NewClient(context.Background(), testProjectID, "myservice", "v1.000", false)
	if err != nil {
		panic(err)
	}
	t.RepanicDefault = false
	return t
}

var ctx context.Context

func init() {
	ctx = context.Background()
}

func TestCatchNothing(t *testing.T) {
	fc := &fakeReportErrorsClient{}
	c := newTestClient(fc)
	defer func() {
		r := fc.req
		if r != nil {
			t.Errorf("got error report, expected none")
		}
	}()
	defer c.Catch(ctx)
}

func commonChecks(t *testing.T, req *erpb.ReportErrorEventRequest, panickingFunction string) {
	if req.Event.ServiceContext.Service != "myservice" {
		t.Errorf("error report didn't contain service name")
	}
	if req.Event.ServiceContext.Version != "v1.000" {
		t.Errorf("error report didn't contain version name")
	}
	if !strings.Contains(req.Event.Message, "hello, error") {
		t.Errorf("error report didn't contain message")
	}
	if !strings.Contains(req.Event.Message, panickingFunction) {
		t.Errorf("error report didn't contain stack trace")
	}
}

func TestCatchPanic(t *testing.T) {
	fc := &fakeReportErrorsClient{}
	c := newTestClient(fc)
	defer func() {
		r := fc.req
		if r == nil {
			t.Fatalf("got no error report, expected one")
		}
		commonChecks(t, r, "errorreporting.TestCatchPanic")
		if !strings.Contains(r.Event.Message, "divide by zero") {
			t.Errorf("error report didn't contain recovered value")
		}
	}()
	defer c.Catch(ctx, WithMessage("hello, error"))
	var x int
	x = x / x
}

func TestCatchPanicNilClient(t *testing.T) {
	buf := new(bytes.Buffer)
	log.SetOutput(buf)
	defer func() {
		recover()
		body := buf.String()
		if !strings.Contains(body, "divide by zero") {
			t.Errorf("error report didn't contain recovered value")
		}
		if !strings.Contains(body, "hello, error") {
			t.Errorf("error report didn't contain message")
		}
		if !strings.Contains(body, "TestCatchPanicNilClient") {
			t.Errorf("error report didn't contain recovered value")
		}
	}()
	var c *Client
	defer c.Catch(ctx, WithMessage("hello, error"))
	var x int
	x = x / x
}

func TestLogFailedReports(t *testing.T) {
	fc := &fakeReportErrorsClient{fail: true}
	c := newTestClient(fc)
	buf := new(bytes.Buffer)
	log.SetOutput(buf)
	defer func() {
		recover()
		body := buf.String()
		if !strings.Contains(body, "hello, error") {
			t.Errorf("error report didn't contain message")
		}
		if !strings.Contains(body, "errorreporting.TestLogFailedReports") {
			t.Errorf("error report didn't contain stack trace")
		}
		if !strings.Contains(body, "divide by zero") {
			t.Errorf("error report didn't contain recovered value")
		}
	}()
	defer c.Catch(ctx, WithMessage("hello, error"))
	var x int
	x = x / x
}

func TestCatchNilPanic(t *testing.T) {
	fc := &fakeReportErrorsClient{}
	c := newTestClient(fc)
	defer func() {
		r := fc.req
		if r == nil {
			t.Fatalf("got no error report, expected one")
		}
		commonChecks(t, r, "errorreporting.TestCatchNilPanic")
		if !strings.Contains(r.Event.Message, "nil") {
			t.Errorf("error report didn't contain recovered value")
		}
	}()
	b := true
	defer c.Catch(ctx, WithMessage("hello, error"), PanicFlag(&b))
	panic(nil)
}

func TestNotCatchNilPanic(t *testing.T) {
	fc := &fakeReportErrorsClient{}
	c := newTestClient(fc)
	defer func() {
		r := fc.req
		if r != nil {
			t.Errorf("got error report, expected none")
		}
	}()
	defer c.Catch(ctx, WithMessage("hello, error"))
	panic(nil)
}

func TestReport(t *testing.T) {
	fc := &fakeReportErrorsClient{}
	c := newTestClient(fc)
	c.Report(ctx, nil, "hello, ", "error")
	r := fc.req
	if r == nil {
		t.Fatalf("got no error report, expected one")
	}
	commonChecks(t, r, "errorreporting.TestReport")
}

func TestReportf(t *testing.T) {
	fc := &fakeReportErrorsClient{}
	c := newTestClient(fc)
	c.Reportf(ctx, nil, "hello, error 2+%d=%d", 2, 2+2)
	r := fc.req
	if r == nil {
		t.Fatalf("got no error report, expected one")
	}
	commonChecks(t, r, "errorreporting.TestReportf")
	if !strings.Contains(r.Event.Message, "2+2=4") {
		t.Errorf("error report didn't contain formatted message")
	}
}
