/*
 * 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"
)

type circular struct {
	Num      int
	Previous *circular
	Next     *circular
}

//JavaClassName  java fully qualified path
func (circular) JavaClassName() string {
	return "circular"
}

func TestRef(t *testing.T) {
	c := &circular{}
	c.Num = 12345
	c.Previous = c
	c.Next = c

	e := NewEncoder()
	err := e.Encode(c)
	if err != nil {
		panic(err)
	}

	bytes := e.Buffer()
	t.Logf("circular bytes hex: %x, string: %s", bytes, string(bytes))
	res, err := NewDecoder(bytes).Decode()
	if err != nil {
		panic(err)
	}
	c1, ok := res.(*circular)
	if !ok {
		t.Fatalf("res:%T is not of type circular", c1)
	}
	t.Logf("encode object: %+v, decode object: %+v", c, c1)
	if c.Num != c1.Num {
		t.Errorf("encoded value %d != decoded value %d", c.Num, c1.Num)
	}
	if c1.Previous != c1.Next {
		t.Errorf("decoded value previous %p != decoded value next %p", c1.Previous, c1.Next)
	}
}

type personT struct {
	Name      string
	Relations []*personT
	Parent    *personT
	Marks     *map[string]*personT
	Tags      map[string]*personT
}

//JavaClassName  java fully qualified path
func (personT) JavaClassName() string {
	return "person"
}

func logRefObject(t *testing.T, n string, i interface{}) {
	t.Logf("ref obj[%s]: %p, %v", n, i, i)
}

func doTestRef(t *testing.T, c interface{}, name string) interface{} {
	e := NewEncoder()
	err := e.Encode(c)
	if err != nil {
		assert.FailNowf(t, "failed to encode", "error: %v", err)
	}
	bytes := e.Buffer()

	t.Logf("%s ref bytes: %s", name, string(bytes))
	t.Logf("%s ref bytes: %x", name, bytes)

	d := NewDecoder(bytes)
	decoded, err := EnsureInterface(d.Decode())
	if err != nil {
		assert.FailNowf(t, "failed to encode", "error: %v", err)
	}
	t.Logf("%s ref decoded: %v", name, decoded)
	return decoded
}

func buildComplexLevelPerson() *personT {
	p1 := &personT{Name: "p1"}
	p2 := &personT{Name: "p2"}
	p3 := &personT{Name: "p3"}
	p4 := &personT{Name: "p4"}
	p5 := &personT{Name: "p5"}
	p6 := &personT{Name: "p6"}

	p1.Parent = p2
	p2.Parent = p3
	p3.Parent = p4

	relations := []*personT{p5, p6}
	p3.Relations = relations
	p4.Relations = relations

	marks := &map[string]*personT{
		"beautiful": p1,
		"tall":      p2,
		"fat":       p3,
	}
	p4.Marks = marks
	p5.Marks = marks

	tags := map[string]*personT{
		"man":   p3,
		"woman": p4,
	}
	p5.Tags = tags
	p6.Tags = tags

	return p1
}

func TestComplexLevelRef(t *testing.T) {
	p1 := buildComplexLevelPerson()
	decoded := doTestRef(t, p1, "person")

	t.Logf("decoded object type: %v", reflect.TypeOf(decoded))
	d1, ok := decoded.(*personT)
	if !ok {
		assert.FailNow(t, "decode object is not a pointer of person")
	}
	logRefObject(t, "d1", d1)

	d2 := d1.Parent
	assert.NotNil(t, d2)
	logRefObject(t, "d2", d2)

	d3 := d2.Parent
	assert.NotNil(t, d3)
	logRefObject(t, "d3", d3)

	d4 := d3.Parent
	logRefObject(t, "d4", d4)

	assert.Equal(t, 2, len(d3.Relations))
	if len(d3.Relations) != 2 {
		assert.FailNow(t, "the length of relation array should be 2")
	}
	d5 := d3.Relations[0]
	logRefObject(t, "d5", d5)
	d6 := d3.Relations[1]
	logRefObject(t, "d6", d6)

	assert.NotNil(t, d4)
	assert.NotNil(t, d5)
	assert.NotNil(t, d6)

	assert.Equal(t, "p1", d1.Name)
	assert.Equal(t, "p2", d2.Name)
	assert.Equal(t, "p3", d3.Name)
	assert.Equal(t, "p4", d4.Name)
	assert.Equal(t, "p5", d5.Name)
	assert.Equal(t, "p6", d6.Name)

	//value equal
	assert.True(t, reflect.DeepEqual(d3.Relations, d4.Relations))

	if d4.Marks == nil {
		assert.FailNow(t, "d4.Marks should not be nil")
	}

	assert.Equal(t, 3, len(*d4.Marks))
	assert.True(t, AddrEqual(d4.Marks, d5.Marks))
	assert.True(t, AddrEqual(d1, (*d4.Marks)["beautiful"]))
	assert.True(t, AddrEqual(d2, (*d4.Marks)["tall"]))
	assert.True(t, AddrEqual(d3, (*d4.Marks)["fat"]))

	if d5.Tags == nil {
		assert.FailNow(t, "d5.Tags should not be nil")
	}
	assert.Equal(t, 2, len(d5.Tags))
	assert.True(t, reflect.DeepEqual(d5.Tags, d6.Tags))
	assert.False(t, AddrEqual(d5.Tags, d6.Tags))
	assert.True(t, AddrEqual(d3, d5.Tags["man"]))
	assert.True(t, AddrEqual(d4, d5.Tags["woman"]))
}
