// 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 bigquery

import (
	"errors"
	"math"
	"reflect"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"

	"cloud.google.com/go/civil"
	"cloud.google.com/go/internal/testutil"
	"golang.org/x/net/context"
	bq "google.golang.org/api/bigquery/v2"
)

var scalarTests = []struct {
	val  interface{}
	want string
}{
	{int64(0), "0"},
	{3.14, "3.14"},
	{3.14159e-87, "3.14159e-87"},
	{true, "true"},
	{"string", "string"},
	{"\u65e5\u672c\u8a9e\n", "\u65e5\u672c\u8a9e\n"},
	{math.NaN(), "NaN"},
	{[]byte("foo"), "Zm9v"}, // base64 encoding of "foo"
	{time.Date(2016, 3, 20, 4, 22, 9, 5000, time.FixedZone("neg1-2", -3720)),
		"2016-03-20 04:22:09.000005-01:02"},
	{civil.Date{2016, 3, 20}, "2016-03-20"},
	{civil.Time{4, 5, 6, 789000000}, "04:05:06.789000"},
	{civil.DateTime{civil.Date{2016, 3, 20}, civil.Time{4, 5, 6, 789000000}}, "2016-03-20 04:05:06.789000"},
}

type S1 struct {
	A int
	B *S2
	C bool
}

type S2 struct {
	D string
	e int
}

var s1 = S1{
	A: 1,
	B: &S2{D: "s"},
	C: true,
}

func sval(s string) bq.QueryParameterValue {
	return bq.QueryParameterValue{Value: s}
}

func TestParamValueScalar(t *testing.T) {
	for _, test := range scalarTests {
		got, err := paramValue(reflect.ValueOf(test.val))
		if err != nil {
			t.Errorf("%v: got %v, want nil", test.val, err)
			continue
		}
		want := sval(test.want)
		if !testutil.Equal(got, want) {
			t.Errorf("%v:\ngot  %+v\nwant %+v", test.val, got, want)
		}
	}
}

func TestParamValueArray(t *testing.T) {
	qpv := bq.QueryParameterValue{ArrayValues: []*bq.QueryParameterValue{
		{Value: "1"},
		{Value: "2"},
	},
	}
	for _, test := range []struct {
		val  interface{}
		want bq.QueryParameterValue
	}{
		{[]int(nil), bq.QueryParameterValue{}},
		{[]int{}, bq.QueryParameterValue{}},
		{[]int{1, 2}, qpv},
		{[2]int{1, 2}, qpv},
	} {
		got, err := paramValue(reflect.ValueOf(test.val))
		if err != nil {
			t.Fatal(err)
		}
		if !testutil.Equal(got, test.want) {
			t.Errorf("%#v:\ngot  %+v\nwant %+v", test.val, got, test.want)
		}
	}
}

func TestParamValueStruct(t *testing.T) {
	got, err := paramValue(reflect.ValueOf(s1))
	if err != nil {
		t.Fatal(err)
	}
	want := bq.QueryParameterValue{
		StructValues: map[string]bq.QueryParameterValue{
			"A": sval("1"),
			"B": bq.QueryParameterValue{
				StructValues: map[string]bq.QueryParameterValue{
					"D": sval("s"),
				},
			},
			"C": sval("true"),
		},
	}
	if !testutil.Equal(got, want) {
		t.Errorf("got  %+v\nwant %+v", got, want)
	}
}

func TestParamValueErrors(t *testing.T) {
	// paramValue lets a few invalid types through, but paramType catches them.
	// Since we never call one without the other that's fine.
	for _, val := range []interface{}{nil, new([]int)} {
		_, err := paramValue(reflect.ValueOf(val))
		if err == nil {
			t.Errorf("%v (%T): got nil, want error", val, val)
		}
	}
}

func TestParamType(t *testing.T) {
	for _, test := range []struct {
		val  interface{}
		want *bq.QueryParameterType
	}{
		{0, int64ParamType},
		{uint32(32767), int64ParamType},
		{3.14, float64ParamType},
		{float32(3.14), float64ParamType},
		{math.NaN(), float64ParamType},
		{true, boolParamType},
		{"", stringParamType},
		{"string", stringParamType},
		{time.Now(), timestampParamType},
		{[]byte("foo"), bytesParamType},
		{[]int{}, &bq.QueryParameterType{Type: "ARRAY", ArrayType: int64ParamType}},
		{[3]bool{}, &bq.QueryParameterType{Type: "ARRAY", ArrayType: boolParamType}},
		{S1{}, &bq.QueryParameterType{
			Type: "STRUCT",
			StructTypes: []*bq.QueryParameterTypeStructTypes{
				{Name: "A", Type: int64ParamType},
				{Name: "B", Type: &bq.QueryParameterType{
					Type: "STRUCT",
					StructTypes: []*bq.QueryParameterTypeStructTypes{
						{Name: "D", Type: stringParamType},
					},
				}},
				{Name: "C", Type: boolParamType},
			},
		}},
	} {
		got, err := paramType(reflect.TypeOf(test.val))
		if err != nil {
			t.Fatal(err)
		}
		if !testutil.Equal(got, test.want) {
			t.Errorf("%v (%T): got %v, want %v", test.val, test.val, got, test.want)
		}
	}
}

func TestParamTypeErrors(t *testing.T) {
	for _, val := range []interface{}{
		nil, uint(0), new([]int), make(chan int),
	} {
		_, err := paramType(reflect.TypeOf(val))
		if err == nil {
			t.Errorf("%v (%T): got nil, want error", val, val)
		}
	}
}

func TestIntegration_ScalarParam(t *testing.T) {
	c := getClient(t)
	for _, test := range scalarTests {
		got, err := paramRoundTrip(c, test.val)
		if err != nil {
			t.Fatal(err)
		}
		if !testutil.Equal(got, test.val, cmp.Comparer(func(t1, t2 time.Time) bool {
			return t1.Round(time.Microsecond).Equal(t2.Round(time.Microsecond))
		})) {
			t.Errorf("\ngot  %#v (%T)\nwant %#v (%T)", got, got, test.val, test.val)
		}
	}
}

func TestIntegration_OtherParam(t *testing.T) {
	c := getClient(t)
	for _, test := range []struct {
		val  interface{}
		want interface{}
	}{
		{[]int(nil), []Value(nil)},
		{[]int{}, []Value(nil)},
		{[]int{1, 2}, []Value{int64(1), int64(2)}},
		{[3]int{1, 2, 3}, []Value{int64(1), int64(2), int64(3)}},
		{S1{}, []Value{int64(0), nil, false}},
		{s1, []Value{int64(1), []Value{"s"}, true}},
	} {
		got, err := paramRoundTrip(c, test.val)
		if err != nil {
			t.Fatal(err)
		}
		if !testutil.Equal(got, test.want) {
			t.Errorf("\ngot  %#v (%T)\nwant %#v (%T)", got, got, test.want, test.want)
		}
	}
}

func paramRoundTrip(c *Client, x interface{}) (Value, error) {
	q := c.Query("select ?")
	q.Parameters = []QueryParameter{{Value: x}}
	it, err := q.Read(context.Background())
	if err != nil {
		return nil, err
	}
	var val []Value
	err = it.Next(&val)
	if err != nil {
		return nil, err
	}
	if len(val) != 1 {
		return nil, errors.New("wrong number of values")
	}
	return val[0], nil
}
