// Licensed to 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. Apache Software Foundation (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 pb

import (
	"time"

	"google.golang.org/protobuf/types/known/timestamppb"

	v1 "github.com/apache/skywalking-banyandb/api/proto/banyandb/v1"
	"github.com/apache/skywalking-banyandb/pkg/convert"
)

var (
	binaryOpsMap = map[string]v1.PairQuery_BinaryOp{
		"=":          v1.PairQuery_BINARY_OP_EQ,
		"!=":         v1.PairQuery_BINARY_OP_NE,
		">":          v1.PairQuery_BINARY_OP_GT,
		">=":         v1.PairQuery_BINARY_OP_GE,
		"<":          v1.PairQuery_BINARY_OP_LT,
		"<=":         v1.PairQuery_BINARY_OP_LE,
		"having":     v1.PairQuery_BINARY_OP_HAVING,
		"not having": v1.PairQuery_BINARY_OP_NOT_HAVING,
	}
)

type EntityCriteriaBuilder struct {
	ec *v1.EntityCriteria
}

func NewEntityCriteriaBuilder() *EntityCriteriaBuilder {
	return &EntityCriteriaBuilder{
		ec: &v1.EntityCriteria{},
	}
}

func (b *EntityCriteriaBuilder) Metadata(group, name string) *EntityCriteriaBuilder {
	b.ec.Metadata = &v1.Metadata{
		Group: group,
		Name:  name,
	}
	return b
}

func (b *EntityCriteriaBuilder) Limit(limit uint32) *EntityCriteriaBuilder {
	b.ec.Limit = limit
	return b
}

func (b *EntityCriteriaBuilder) Offset(offset uint32) *EntityCriteriaBuilder {
	b.ec.Offset = offset
	return b
}

func (b *EntityCriteriaBuilder) Fields(items ...interface{}) *EntityCriteriaBuilder {
	if len(items)%3 != 0 {
		panic("expect even number of arguments")
	}

	b.ec.Fields = make([]*v1.PairQuery, len(items)/3)
	for i := 0; i < len(items)/3; i++ {
		key, op, values := items[i*3+0], items[i*3+1], items[i*3+2]
		b.ec.Fields[i] = &v1.PairQuery{
			Op:        binaryOpsMap[op.(string)],
			Condition: buildPair(key.(string), values),
		}
	}

	return b
}

func buildPair(key string, value interface{}) *v1.TypedPair {
	switch v := value.(type) {
	case int:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: []int64{int64(v)},
				},
			},
		}
	case []int:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: convert.IntToInt64(v...),
				},
			},
		}
	case int8:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: []int64{int64(v)},
				},
			},
		}
	case []int8:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: convert.Int8ToInt64(v...),
				},
			},
		}
	case int16:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: []int64{int64(v)},
				},
			},
		}
	case []int16:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: convert.Int16ToInt64(v...),
				},
			},
		}
	case int32:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: []int64{int64(v)},
				},
			},
		}
	case []int32:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: convert.Int32ToInt64(v...),
				},
			},
		}
	case int64:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: []int64{v},
				},
			},
		}
	case []int64:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_IntPair{
				IntPair: &v1.IntPair{
					Key:    key,
					Values: v,
				},
			},
		}
	case string:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_StrPair{
				StrPair: &v1.StrPair{
					Key:    key,
					Values: []string{v},
				},
			},
		}
	case []string:
		return &v1.TypedPair{
			Typed: &v1.TypedPair_StrPair{
				StrPair: &v1.StrPair{
					Key:    key,
					Values: v,
				},
			},
		}
	default:
		panic("not supported value type")
	}
}

func (b *EntityCriteriaBuilder) Projection(projections ...string) *EntityCriteriaBuilder {
	b.ec.Projection = &v1.Projection{KeyNames: projections}
	return b
}

func (b *EntityCriteriaBuilder) OrderBy(fieldName string, sort v1.QueryOrder_Sort) *EntityCriteriaBuilder {
	b.ec.OrderBy = &v1.QueryOrder{
		KeyName: fieldName,
		Sort:    sort,
	}
	return b
}

func (b *EntityCriteriaBuilder) TimeRange(sT, eT time.Time) *EntityCriteriaBuilder {
	b.ec.TimeRange = &v1.TimeRange{
		Begin: timestamppb.New(sT),
		End:   timestamppb.New(eT),
	}
	return b
}

func (b *EntityCriteriaBuilder) Build() *v1.EntityCriteria {
	return b.ec
}

type QueryEntityBuilder struct {
	qe *v1.Entity
}

func NewQueryEntityBuilder() *QueryEntityBuilder {
	return &QueryEntityBuilder{qe: &v1.Entity{}}
}

func (qeb *QueryEntityBuilder) EntityID(entityID string) *QueryEntityBuilder {
	qeb.qe.EntityId = entityID
	return qeb
}

func (qeb *QueryEntityBuilder) Timestamp(t time.Time) *QueryEntityBuilder {
	qeb.qe.Timestamp = timestamppb.New(t)
	return qeb
}

func (qeb *QueryEntityBuilder) Fields(items ...interface{}) *QueryEntityBuilder {
	if len(items)%2 != 0 {
		panic("invalid fields list")
	}

	l := len(items) / 2

	qeb.qe.Fields = make([]*v1.TypedPair, l)
	for i := 0; i < l; i++ {
		key, values := items[i*2+0], items[i*2+1]
		qeb.qe.Fields[i] = buildPair(key.(string), values)
	}

	return qeb
}

func (qeb *QueryEntityBuilder) Build() *v1.Entity {
	return qeb.qe
}
