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

import (
	perrors "github.com/pkg/errors"
)

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

func init() {
	RegisterPOJO(&java_sql_time.Date{})
	RegisterPOJO(&java_sql_time.Time{})
	SetJavaSqlTimeSerialize(&java_sql_time.Date{})
	SetJavaSqlTimeSerialize(&java_sql_time.Time{})
}

// SetJavaSqlTimeSerialize register serializer for java.sql.Time & java.sql.Date
func SetJavaSqlTimeSerialize(time java_sql_time.JavaSqlTime) {
	name := time.JavaClassName()
	SetSerializer(name, JavaSqlTimeSerializer{})
}

// JavaSqlTimeSerializer used to encode & decode java.sql.Time & java.sql.Date
type JavaSqlTimeSerializer struct{}

// nolint
func (JavaSqlTimeSerializer) EncObject(e *Encoder, vv POJO) error {
	var (
		idx       int
		err       error
		clsDef    *ClassInfo
		className string
		ptrV      reflect.Value
	)

	// ensure ptrV is pointer to know vv is type JavaSqlTime or not
	ptrV = reflect.ValueOf(vv)
	if reflect.TypeOf(vv).Kind() != reflect.Ptr {
		ptrV = PackPtr(ptrV)
	}
	v, ok := ptrV.Interface().(java_sql_time.JavaSqlTime)
	if !ok {
		return perrors.New("can not be converted into java sql time object")
	}
	className = v.JavaClassName()
	if className == "" {
		return perrors.New("class name empty")
	}
	tValue := reflect.ValueOf(vv)
	// check ref
	if n, ok := e.checkRefMap(tValue); ok {
		e.buffer = encRef(e.buffer, n)
		return nil
	}

	// write object definition
	idx = e.classIndex(v.JavaClassName())

	if idx == -1 {
		idx, ok = checkPOJORegistry(vv)
		if !ok {
			idx = RegisterPOJO(v)
		}
		_, clsDef, err = getStructDefByIndex(idx)
		if err != nil {
			return perrors.WithStack(err)
		}
		idx = len(e.classInfoList)
		e.classInfoList = append(e.classInfoList, clsDef)
		e.buffer = append(e.buffer, clsDef.buffer...)
	}
	e.buffer = e.buffer[0 : len(e.buffer)-1]
	e.buffer = encInt32(e.buffer, 1)
	e.buffer = encString(e.buffer, "value")

	// write object instance
	if byte(idx) <= OBJECT_DIRECT_MAX {
		e.buffer = encByte(e.buffer, byte(idx)+BC_OBJECT_DIRECT)
	} else {
		e.buffer = encByte(e.buffer, BC_OBJECT)
		e.buffer = encInt32(e.buffer, int32(idx))
	}
	e.buffer = encDateInMs(e.buffer, v.GetTime())
	return nil
}

// nolint
func (JavaSqlTimeSerializer) DecObject(d *Decoder, typ reflect.Type, cls *ClassInfo) (interface{}, error) {
	if typ.Kind() != reflect.Struct {
		return nil, perrors.Errorf("wrong type expect Struct but get:%s", typ.String())
	}

	vRef := reflect.New(typ)
	// add pointer ref so that ref the same object
	d.appendRefs(vRef.Interface())

	tag, err := d.ReadByte()
	if perrors.Is(err, io.EOF) {
		return nil, err
	}
	date, err := d.decDate(int32(tag))
	if err != nil {
		return nil, perrors.WithStack(err)
	}
	sqlTime := vRef.Interface()

	result, ok := sqlTime.(java_sql_time.JavaSqlTime)
	if !ok {
		panic("result type is not sql time, please check the whether the conversion is ok")
	}
	result.SetTime(date)
	return result, nil
}
