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

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

/////////////////////////////////////////
// Date
/////////////////////////////////////////

var ZeroDate = time.Time{}

// # time in UTC encoded as 64-bit long milliseconds since epoch
// ::= x4a b7 b6 b5 b4 b3 b2 b1 b0
// ::= x4b b3 b2 b1 b0       # minutes since epoch
func encDateInMs(b []byte, i interface{}) []byte {
	value := UnpackPtrValue(reflect.ValueOf(i))
	vi := value.Interface().(time.Time)
	if vi == ZeroDate {
		return append(b, BC_NULL)
	}
	b = append(b, BC_DATE)
	return append(b, PackInt64(vi.UnixNano()/1e6)...)
}

func encDateInMimute(b []byte, v time.Time) []byte {
	b = append(b, BC_DATE_MINUTE)
	return append(b, PackInt32(int32(v.UnixNano()/60e9))...)
}

/////////////////////////////////////////
// Date
/////////////////////////////////////////

// # time in UTC encoded as 64-bit long milliseconds since epoch
// ::= x4a b7 b6 b5 b4 b3 b2 b1 b0
// ::= x4b b3 b2 b1 b0       # minutes since epoch
func (d *Decoder) decDate(flag int32) (time.Time, error) {
	var (
		err error
		l   int
		tag byte
		buf [8]byte
		s   []byte
		i64 int64
		t   time.Time
	)

	if flag != TAG_READ {
		tag = byte(flag)
	} else {
		tag, _ = d.ReadByte()
	}

	switch {
	case tag == BC_NULL:
		return ZeroDate, nil
	case tag == BC_DATE: //'d': //date
		s = buf[:8]
		l, err = d.nextFull(s)
		if err != nil {
			return t, err
		}
		if l != 8 {
			return t, ErrNotEnoughBuf
		}
		i64 = UnpackInt64(s)
		return time.Unix(i64/1000, i64%1000*10e5), nil
		// return time.Unix(i64/1000, i64*100), nil

	case tag == BC_DATE_MINUTE:
		s = buf[:4]
		l, err = d.nextFull(s)
		if err != nil {
			return t, err
		}
		if l != 4 {
			return t, ErrNotEnoughBuf
		}
		i64 = int64(UnpackInt32(s))
		return time.Unix(i64*60, 0), nil

	default:
		return t, perrors.Errorf("decDate Invalid type: %v", tag)
	}
}
