/*
 * 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.
 */

// Unit test for decoding hessian2 based on official api with doc on
// http://javadoc4.caucho.com/com/caucho/hessian/test/TestHessian2.html.
// One can call the api by running the local test_hessian.jar or sending
// a request to the remote server http://hessian.caucho.com/test/test
// directly.

package hessian

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"reflect"
	"testing"
	"unsafe"
)

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

import (
	"github.com/apache/dubbo-go-hessian2/java_exception"
)

const (
	hessianJar = "test_hessian/target/test_hessian-1.0.0.jar"
	testString = "hello, world! 你好，世界！"
)

func isFileExist(file string) bool {
	stat, err := os.Stat(file)
	if err != nil {
		return false
	}

	return !stat.IsDir()
}

func genHessianJar() {
	existFlag := isFileExist(hessianJar)
	if existFlag {
		return
	}

	cmd := exec.Command("mvn", "clean", "package")
	cmd.Dir = "./test_hessian"
	out, err := cmd.Output()
	if err != nil {
		log.Fatalf("after exec command 'mvn clean package', got error:%v, error output:%v",
			err, string(out))
	}
}

func getJavaReply(method, className string) []byte {
	genHessianJar()
	log.Println("get java reply: ", className, method)
	cmdArgs := []string{"-jar", hessianJar, method}
	if className != "" {
		cmdArgs = append(cmdArgs, className)
	}
	cmd := exec.Command("java", cmdArgs...)
	out, err := cmd.Output()
	if err != nil {
		log.Fatal(cmd.Args, err)
	}
	return out
}

func decodeJavaResponse(method, className string, skip bool) (interface{}, error) {
	b := getJavaReply(method, className)
	var d *Decoder
	if skip {
		d = NewDecoderWithSkip(b)
	} else {
		d = NewDecoder(b)
	}
	r, e := d.Decode()
	if e != nil {
		return nil, e
	}
	return r, nil
}

func testDecodeFramework(t *testing.T, method string, expected interface{}) {
	testDecodeJavaData(t, method, "", false, expected)
}

func testDecodeFrameworkWithSkip(t *testing.T, method string, expected interface{}) {
	testDecodeJavaData(t, method, "", true, expected)
}

func testDecodeJavaData(t *testing.T, method, className string, skip bool, expected interface{}) {
	r, e := decodeJavaResponse(method, className, skip)
	if e != nil {
		t.Errorf("%s: decode fail with error: %v", method, e)
		return
	}

	tmp, ok := r.(*_refHolder)
	if ok {
		r = tmp.value.Interface()
	}
	trow, o1 := r.(java_exception.Throwabler)
	expe, o2 := expected.(java_exception.Throwabler)
	if o1 && o2 {
		log.Println(reflect.TypeOf(trow), reflect.TypeOf(trow).Elem().Name())
		if trow.Error() == expe.Error() && reflect.TypeOf(trow).Elem().Name() == reflect.TypeOf(expe).Elem().Name() {
			return
		}
		t.Errorf("%s: got %v, wanted %v", method, r, expected)
	} else if !reflect.DeepEqual(r, expected) {
		t.Errorf("%s: got %v, wanted %v", method, r, expected)
	}
}

func testDecodeFrameworkFunc(t *testing.T, method string, expected func(interface{})) {
	r, e := decodeJavaResponse(method, "", false)
	if e != nil {
		t.Errorf("%s: decode fail with error %v", method, e)
		return
	}

	tmp, ok := r.(*_refHolder)
	if ok {
		r = tmp.value.Interface()
	}
	expected(r)
}

func mustDecodeObject(t *testing.T, b []byte) interface{} {
	d := NewDecoder(b)
	res, err := d.Decode()
	if err != nil {
		t.Error(err)
		t.FailNow()
	}
	return res
}

func TestUserDefindeException(t *testing.T) {
	expect := &UnknownException{
		DetailMessage: "throw UserDefindException",
	}
	testDecodeFramework(t, "throw_UserDefindException", expect)
}

type Circular214 struct {
	Num      int
	Previous *Circular214
	Next     *Circular214
	Bytes    []byte
}

func (Circular214) JavaClassName() string {
	return "com.company.Circular"
}

func (c *Circular214) String() string {
	return fmt.Sprintf("Addr:%p, Num: %d, Previous: %p, Next: %p, Bytes: %s", c, c.Num, c.Previous, c.Next, c.Bytes)
}

func TestIssue214(t *testing.T) {
	c := &Circular214{}
	c.Num = 1234
	c.Previous = c
	c.Next = c
	c.Bytes = []byte(`{"a":"b"}`)
	e := NewEncoder()
	err := e.Encode(c)
	if err != nil {
		assert.FailNow(t, fmt.Sprintf("%v", err))
		return
	}

	bytes := e.Buffer()
	decoder := NewDecoder(bytes)
	decode, err := decoder.Decode()
	if err != nil {
		assert.FailNow(t, fmt.Sprintf("%v", err))
		return
	}
	t.Log(decode)
	assert.True(t, reflect.DeepEqual(c, decode))
}

type Issue299Args1 struct {
	Label string
	Key   string
}

func (Issue299Args1) JavaClassName() string {
	return "com.test.Issue299Args1"
}

type Issue299MockData struct {
	SliceArgs []interface{}
	MapArgs   map[string]interface{}
}

func (Issue299MockData) JavaClassName() string {
	return "com.test.Issue299MockData"
}

func TestIssue299HessianDecode(t *testing.T) {
	RegisterPOJO(new(Issue299Args1))
	RegisterPOJO(new(Issue299MockData))

	d := &Issue299MockData{
		SliceArgs: []interface{}{
			[]*Issue299Args1{
				{Label: "1", Key: "2"},
			},
		},
		MapArgs: map[string]interface{}{
			"interface_slice": []interface{}{
				"MyName",
			},
			"interface_map": map[interface{}]interface{}{
				"k1": "v1",
			},
		},
	}

	encoder := NewEncoder()
	err := encoder.Encode(d)
	if err != nil {
		t.Errorf("encode obj error: %v", err)
		return
	}
	decoder := NewDecoder(encoder.Buffer())
	doInterface, err := decoder.Decode()
	if err != nil {
		t.Errorf("decode obj error: %v", err)
		return
	}
	do := doInterface.(*Issue299MockData)
	if !reflect.DeepEqual(d, do) {
		t.Errorf("not equal d: %#v, do: %#v", d, do)
		return
	}
}

type Issue323B struct {
	Num int
}

func (b *Issue323B) JavaClassName() string {
	return "B"
}

type Issue323BB struct {
	List1 []*Issue323B
	List2 []*Issue323B
}

func (bb *Issue323BB) JavaClassName() string {
	return "BB"
}

func TestIssue323(t *testing.T) {
	RegisterPOJO(&Issue323B{})
	RegisterPOJO(&Issue323BB{})
	a1 := &Issue323B{
		Num: 1,
	}
	a2 := &Issue323B{
		Num: 2,
	}
	list := []*Issue323B{a1, a2}
	b := &Issue323BB{
		List1: list,
		List2: list,
	}
	e := NewEncoder()
	err := e.Encode(b)
	assert.Nil(t, err)
	fmt.Println(b)

	d := NewDecoder(e.Buffer())
	res, err := d.Decode()
	assert.Nil(t, err)
	fmt.Println(res)
	assert.True(t, reflect.DeepEqual(b, res))

	decodB, ok := res.(*Issue323BB)
	if !ok {
		t.Log("res is not Issue323BB")
		t.FailNow()
	}

	// list1 and list2 should be reference to the same one.
	assert.Equal(t, unsafe.Pointer(reflect.ValueOf(decodB.List1).Pointer()),
		unsafe.Pointer(reflect.ValueOf(decodB.List2).Pointer()))
}
