/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 hessian

import (
	"reflect"
	"testing"
)

import (
	"github.com/stretchr/testify/assert"
)

func doTestReflectResponse(t *testing.T, in interface{}, out interface{}) {
	err := ReflectResponse(in, out)
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	result := UnpackPtrValue(reflect.ValueOf(out)).Interface()

	equal := reflect.DeepEqual(in, result)
	if !equal {
		t.Errorf("expect [%v]: %v, but got [%v]: %v", reflect.TypeOf(in), in, reflect.TypeOf(result), result)
	}
}

func TestReflectResponse(t *testing.T) {
	var b bool
	doTestReflectResponse(t, true, &b)
	doTestReflectResponse(t, false, &b)

	var i int
	doTestReflectResponse(t, 123, &i)
	doTestReflectResponse(t, 234, &i)

	var i16 int16
	doTestReflectResponse(t, int16(456), &i16)

	var i64 int64
	doTestReflectResponse(t, int64(789), &i64)

	var s string
	doTestReflectResponse(t, "hello world", &s)

	type rr struct {
		Name string
		Num  int
	}

	var r1 rr
	doTestReflectResponse(t, rr{"dubbogo", 32}, &r1)

	// ------ map test -------
	m1 := make(map[interface{}]interface{})
	var m1r map[interface{}]interface{}
	m1["hello"] = "world"
	m1[1] = "go"
	m1["dubbo"] = 666
	doTestReflectResponse(t, m1, &m1r)

	m2 := make(map[string]string)
	var m2r map[string]string
	m2["hello"] = "world"
	m2["dubbo"] = "666"
	doTestReflectResponse(t, m2, &m2r)

	m3 := make(map[string]rr)
	var m3r map[string]rr
	m3["dubbo"] = rr{"hello", 123}
	m3["go"] = rr{"world", 456}
	doTestReflectResponse(t, m3, &m3r)

	// ------ slice test -------
	s1 := []string{"abc", "def", "hello", "world"}
	var s1r []string
	doTestReflectResponse(t, s1, &s1r)

	s2 := []rr{{"dubbo", 666}, {"go", 999}}
	var s2r []rr
	doTestReflectResponse(t, s2, &s2r)

	s3 := []interface{}{rr{"dubbo", 666}, 123, "hello"}
	var s3r []interface{}
	doTestReflectResponse(t, s3, &s3r)

	// ------ interface test -------
	in1 := []interface{}{rr{"dubbo", 666}, 123, "hello"}
	var inr1 *interface{}
	doTestReflectResponse(t, in1, reflect.New(reflect.TypeOf(inr1).Elem()).Interface())

	in2 := make(map[string]rr)
	var inr2 map[string]rr
	m3["dubbo"] = rr{"hello", 123}
	m3["go"] = rr{"world", 456}
	doTestReflectResponse(t, in2, &inr2)
}

// separately test copy normal map to map[interface{}]interface{}
func TestCopyMap(t *testing.T) {
	type rr struct {
		Name string
		Num  int
	}

	m3 := make(map[string]rr)
	var m3r map[interface{}]interface{}
	r1 := rr{"hello", 123}
	r2 := rr{"world", 456}
	m3["dubbo"] = r1
	m3["go"] = r2

	err := ReflectResponse(m3, &m3r)
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	assert.Equal(t, 2, len(m3r))

	rr1, ok := m3r["dubbo"]
	assert.True(t, ok)
	assert.True(t, reflect.DeepEqual(r1, rr1))

	rr2, ok := m3r["go"]
	assert.True(t, ok)
	assert.True(t, reflect.DeepEqual(r2, rr2))
}

// separately test copy normal slice to []interface{}
func TestCopySlice(t *testing.T) {
	type rr struct {
		Name string
		Num  int
	}

	r1 := rr{"hello", 123}
	r2 := rr{"world", 456}

	s1 := []rr{r1, r2}
	var s1r []interface{}

	err := ReflectResponse(s1, &s1r)
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	assert.Equal(t, 2, len(s1r))
	assert.True(t, reflect.DeepEqual(r1, s1r[0]))
	assert.True(t, reflect.DeepEqual(r2, s1r[1]))
}

func TestIsSupportResponseAttachment(t *testing.T) {
	is := isSupportResponseAttachment("2.0.10")
	assert.False(t, is)

	is = isSupportResponseAttachment("2.5.3")
	assert.False(t, is)

	is = isSupportResponseAttachment("2.6.2")
	assert.False(t, is)

	is = isSupportResponseAttachment("1.5.5")
	assert.False(t, is)

	is = isSupportResponseAttachment("0.0.0")
	assert.False(t, is)

	is = isSupportResponseAttachment("2.0.2")
	assert.True(t, is)

	is = isSupportResponseAttachment("2.7.2")
	assert.True(t, is)
}

func TestVersion2Int(t *testing.T) {
	v := version2Int("2.1.3")
	assert.Equal(t, 2010300, v)

	v = version2Int("22.11.33")
	assert.Equal(t, 22113300, v)

	v = version2Int("222.111.333")
	assert.Equal(t, 223143300, v)

	v = version2Int("220.110.333")
	assert.Equal(t, 221133300, v)

	v = version2Int("229.119.333")
	assert.Equal(t, 230223300, v)

	v = version2Int("2222.1111.3333")
	assert.Equal(t, 2233443300, v)

	v = version2Int("2.11")
	assert.Equal(t, 211, v)

	v = version2Int("2.1.3.4")
	assert.Equal(t, 2010304, v)

	v = version2Int("2.1.3.4.5")
	assert.Equal(t, 201030405, v)
}
