// Copyright (C) MongoDB, Inc. 2017-present.
//
// Licensed 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

package bsonrw

import (
	"encoding/base64"
	"errors"
	"fmt"
	"math"
	"strconv"
	"time"

	"github.com/mongodb/mongo-go-driver/bson/bsontype"
	"github.com/mongodb/mongo-go-driver/bson/primitive"
)

func wrapperKeyBSONType(key string) bsontype.Type {
	switch string(key) {
	case "$numberInt":
		return bsontype.Int32
	case "$numberLong":
		return bsontype.Int64
	case "$oid":
		return bsontype.ObjectID
	case "$symbol":
		return bsontype.Symbol
	case "$numberDouble":
		return bsontype.Double
	case "$numberDecimal":
		return bsontype.Decimal128
	case "$binary":
		return bsontype.Binary
	case "$code":
		return bsontype.JavaScript
	case "$scope":
		return bsontype.CodeWithScope
	case "$timestamp":
		return bsontype.Timestamp
	case "$regularExpression":
		return bsontype.Regex
	case "$dbPointer":
		return bsontype.DBPointer
	case "$date":
		return bsontype.DateTime
	case "$ref":
		fallthrough
	case "$id":
		fallthrough
	case "$db":
		return bsontype.EmbeddedDocument // dbrefs aren't bson types
	case "$minKey":
		return bsontype.MinKey
	case "$maxKey":
		return bsontype.MaxKey
	case "$undefined":
		return bsontype.Undefined
	}

	return bsontype.EmbeddedDocument
}

func (ejv *extJSONValue) parseBinary() (b []byte, subType byte, err error) {
	if ejv.t != bsontype.EmbeddedDocument {
		return nil, 0, fmt.Errorf("$binary value should be object, but instead is %s", ejv.t)
	}

	binObj := ejv.v.(*extJSONObject)
	bFound := false
	stFound := false

	for i, key := range binObj.keys {
		val := binObj.values[i]

		switch key {
		case "base64":
			if bFound {
				return nil, 0, errors.New("duplicate base64 key in $binary")
			}

			if val.t != bsontype.String {
				return nil, 0, fmt.Errorf("$binary base64 value should be string, but instead is %s", val.t)
			}

			base64Bytes, err := base64.StdEncoding.DecodeString(val.v.(string))
			if err != nil {
				return nil, 0, fmt.Errorf("invalid $binary base64 string: %s", val.v.(string))
			}

			b = base64Bytes
			bFound = true
		case "subType":
			if stFound {
				return nil, 0, errors.New("duplicate subType key in $binary")
			}

			if val.t != bsontype.String {
				return nil, 0, fmt.Errorf("$binary subType value should be string, but instead is %s", val.t)
			}

			i, err := strconv.ParseInt(val.v.(string), 16, 64)
			if err != nil {
				return nil, 0, fmt.Errorf("invalid $binary subType string: %s", val.v.(string))
			}

			subType = byte(i)
			stFound = true
		default:
			return nil, 0, fmt.Errorf("invalid key in $binary object: %s", key)
		}
	}

	if !bFound {
		return nil, 0, errors.New("missing base64 field in $binary object")
	}

	if !stFound {
		return nil, 0, errors.New("missing subType field in $binary object")

	}

	return b, subType, nil
}

func (ejv *extJSONValue) parseDBPointer() (ns string, oid primitive.ObjectID, err error) {
	if ejv.t != bsontype.EmbeddedDocument {
		return "", primitive.NilObjectID, fmt.Errorf("$dbPointer value should be object, but instead is %s", ejv.t)
	}

	dbpObj := ejv.v.(*extJSONObject)
	oidFound := false
	nsFound := false

	for i, key := range dbpObj.keys {
		val := dbpObj.values[i]

		switch key {
		case "$ref":
			if nsFound {
				return "", primitive.NilObjectID, errors.New("duplicate $ref key in $dbPointer")
			}

			if val.t != bsontype.String {
				return "", primitive.NilObjectID, fmt.Errorf("$dbPointer $ref value should be string, but instead is %s", val.t)
			}

			ns = val.v.(string)
			nsFound = true
		case "$id":
			if oidFound {
				return "", primitive.NilObjectID, errors.New("duplicate $id key in $dbPointer")
			}

			if val.t != bsontype.String {
				return "", primitive.NilObjectID, fmt.Errorf("$dbPointer $id value should be string, but instead is %s", val.t)
			}

			oid, err = primitive.ObjectIDFromHex(val.v.(string))
			if err != nil {
				return "", primitive.NilObjectID, err
			}

			oidFound = true
		default:
			return "", primitive.NilObjectID, fmt.Errorf("invalid key in $dbPointer object: %s", key)
		}
	}

	if !nsFound {
		return "", oid, errors.New("missing $ref field in $dbPointer object")
	}

	if !oidFound {
		return "", oid, errors.New("missing $id field in $dbPointer object")
	}

	return ns, oid, nil
}

const rfc3339Milli = "2006-01-02T15:04:05.999Z07:00"

func (ejv *extJSONValue) parseDateTime() (int64, error) {
	switch ejv.t {
	case bsontype.Int32:
		return int64(ejv.v.(int32)), nil
	case bsontype.Int64:
		return ejv.v.(int64), nil
	case bsontype.String:
		return parseDatetimeString(ejv.v.(string))
	case bsontype.EmbeddedDocument:
		return parseDatetimeObject(ejv.v.(*extJSONObject))
	default:
		return 0, fmt.Errorf("$date value should be string or object, but instead is %s", ejv.t)
	}
}

func parseDatetimeString(data string) (int64, error) {
	t, err := time.Parse(rfc3339Milli, data)
	if err != nil {
		return 0, fmt.Errorf("invalid $date value string: %s", data)
	}

	return t.UnixNano() / 1e6, nil
}

func parseDatetimeObject(data *extJSONObject) (d int64, err error) {
	dFound := false

	for i, key := range data.keys {
		val := data.values[i]

		switch key {
		case "$numberLong":
			if dFound {
				return 0, errors.New("duplicate $numberLong key in $date")
			}

			if val.t != bsontype.String {
				return 0, fmt.Errorf("$date $numberLong field should be string, but instead is %s", val.t)
			}

			d, err = val.parseInt64()
			if err != nil {
				return 0, err
			}
			dFound = true
		default:
			return 0, fmt.Errorf("invalid key in $date object: %s", key)
		}
	}

	if !dFound {
		return 0, errors.New("missing $numberLong field in $date object")
	}

	return d, nil
}

func (ejv *extJSONValue) parseDecimal128() (primitive.Decimal128, error) {
	if ejv.t != bsontype.String {
		return primitive.Decimal128{}, fmt.Errorf("$numberDecimal value should be string, but instead is %s", ejv.t)
	}

	d, err := primitive.ParseDecimal128(ejv.v.(string))
	if err != nil {
		return primitive.Decimal128{}, fmt.Errorf("$invalid $numberDecimal string: %s", ejv.v.(string))
	}

	return d, nil
}

func (ejv *extJSONValue) parseDouble() (float64, error) {
	if ejv.t == bsontype.Double {
		return ejv.v.(float64), nil
	}

	if ejv.t != bsontype.String {
		return 0, fmt.Errorf("$numberDouble value should be string, but instead is %s", ejv.t)
	}

	switch string(ejv.v.(string)) {
	case "Infinity":
		return math.Inf(1), nil
	case "-Infinity":
		return math.Inf(-1), nil
	case "NaN":
		return math.NaN(), nil
	}

	f, err := strconv.ParseFloat(ejv.v.(string), 64)
	if err != nil {
		return 0, err
	}

	return f, nil
}

func (ejv *extJSONValue) parseInt32() (int32, error) {
	if ejv.t == bsontype.Int32 {
		return ejv.v.(int32), nil
	}

	if ejv.t != bsontype.String {
		return 0, fmt.Errorf("$numberInt value should be string, but instead is %s", ejv.t)
	}

	i, err := strconv.ParseInt(ejv.v.(string), 10, 64)
	if err != nil {
		return 0, err
	}

	if i < math.MinInt32 || i > math.MaxInt32 {
		return 0, fmt.Errorf("$numberInt value should be int32 but instead is int64: %d", i)
	}

	return int32(i), nil
}

func (ejv *extJSONValue) parseInt64() (int64, error) {
	if ejv.t == bsontype.Int64 {
		return ejv.v.(int64), nil
	}

	if ejv.t != bsontype.String {
		return 0, fmt.Errorf("$numberLong value should be string, but instead is %s", ejv.t)
	}

	i, err := strconv.ParseInt(ejv.v.(string), 10, 64)
	if err != nil {
		return 0, err
	}

	return i, nil
}

func (ejv *extJSONValue) parseJavascript() (code string, err error) {
	if ejv.t != bsontype.String {
		return "", fmt.Errorf("$code value should be string, but instead is %s", ejv.t)
	}

	return ejv.v.(string), nil
}

func (ejv *extJSONValue) parseMinMaxKey(minmax string) error {
	if ejv.t != bsontype.Int32 {
		return fmt.Errorf("$%sKey value should be int32, but instead is %s", minmax, ejv.t)
	}

	if ejv.v.(int32) != 1 {
		return fmt.Errorf("$%sKey value must be 1, but instead is %d", minmax, ejv.v.(int32))
	}

	return nil
}

func (ejv *extJSONValue) parseObjectID() (primitive.ObjectID, error) {
	if ejv.t != bsontype.String {
		return primitive.NilObjectID, fmt.Errorf("$oid value should be string, but instead is %s", ejv.t)
	}

	return primitive.ObjectIDFromHex(ejv.v.(string))
}

func (ejv *extJSONValue) parseRegex() (pattern, options string, err error) {
	if ejv.t != bsontype.EmbeddedDocument {
		return "", "", fmt.Errorf("$regularExpression value should be object, but instead is %s", ejv.t)
	}

	regexObj := ejv.v.(*extJSONObject)
	patFound := false
	optFound := false

	for i, key := range regexObj.keys {
		val := regexObj.values[i]

		switch string(key) {
		case "pattern":
			if patFound {
				return "", "", errors.New("duplicate pattern key in $regularExpression")
			}

			if val.t != bsontype.String {
				return "", "", fmt.Errorf("$regularExpression pattern value should be string, but instead is %s", val.t)
			}

			pattern = val.v.(string)
			patFound = true
		case "options":
			if optFound {
				return "", "", errors.New("duplicate options key in $regularExpression")
			}

			if val.t != bsontype.String {
				return "", "", fmt.Errorf("$regularExpression options value should be string, but instead is %s", val.t)
			}

			options = val.v.(string)
			optFound = true
		default:
			return "", "", fmt.Errorf("invalid key in $regularExpression object: %s", key)
		}
	}

	if !patFound {
		return "", "", errors.New("missing pattern field in $regularExpression object")
	}

	if !optFound {
		return "", "", errors.New("missing options field in $regularExpression object")

	}

	return pattern, options, nil
}

func (ejv *extJSONValue) parseSymbol() (string, error) {
	if ejv.t != bsontype.String {
		return "", fmt.Errorf("$symbol value should be string, but instead is %s", ejv.t)
	}

	return ejv.v.(string), nil
}

func (ejv *extJSONValue) parseTimestamp() (t, i uint32, err error) {
	if ejv.t != bsontype.EmbeddedDocument {
		return 0, 0, fmt.Errorf("$timestamp value should be object, but instead is %s", ejv.t)
	}

	handleKey := func(key string, val *extJSONValue, flag bool) (uint32, error) {
		if flag {
			return 0, fmt.Errorf("duplicate %s key in $timestamp", key)
		}

		switch val.t {
		case bsontype.Int32:
			if val.v.(int32) < 0 {
				return 0, fmt.Errorf("$timestamp %s number should be uint32: %s", key, string(val.v.(int32)))
			}

			return uint32(val.v.(int32)), nil
		case bsontype.Int64:
			if val.v.(int64) < 0 || uint32(val.v.(int64)) > math.MaxUint32 {
				return 0, fmt.Errorf("$timestamp %s number should be uint32: %s", key, string(val.v.(int32)))
			}

			return uint32(val.v.(int64)), nil
		default:
			return 0, fmt.Errorf("$timestamp %s value should be uint32, but instead is %s", key, val.t)
		}
	}

	tsObj := ejv.v.(*extJSONObject)
	tFound := false
	iFound := false

	for j, key := range tsObj.keys {
		val := tsObj.values[j]

		switch key {
		case "t":
			if t, err = handleKey(key, val, tFound); err != nil {
				return 0, 0, err
			}

			tFound = true
		case "i":
			if i, err = handleKey(key, val, iFound); err != nil {
				return 0, 0, err
			}

			iFound = true
		default:
			return 0, 0, fmt.Errorf("invalid key in $timestamp object: %s", key)
		}
	}

	if !tFound {
		return 0, 0, errors.New("missing t field in $timestamp object")
	}

	if !iFound {
		return 0, 0, errors.New("missing i field in $timestamp object")
	}

	return t, i, nil
}

func (ejv *extJSONValue) parseUndefined() error {
	if ejv.t != bsontype.Boolean {
		return fmt.Errorf("undefined value should be boolean, but instead is %s", ejv.t)
	}

	if !ejv.v.(bool) {
		return fmt.Errorf("$undefined balue boolean should be true, but instead is %v", ejv.v.(bool))
	}

	return nil
}
