// 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 plugin

import (
	"errors"
	"sort"
	"sync"
	"testing"
	"time"

	"github.com/ReneKroon/ttlcache/v2"
	A6 "github.com/api7/ext-plugin-proto/go/A6"
	pc "github.com/api7/ext-plugin-proto/go/A6/PrepareConf"
	flatbuffers "github.com/google/flatbuffers/go"
	"github.com/stretchr/testify/assert"
)

func TestPrepareConf(t *testing.T) {
	InitConfCache(10 * time.Millisecond)

	builder := flatbuffers.NewBuilder(1024)
	pc.ReqStart(builder)
	root := pc.ReqEnd(builder)
	builder.Finish(root)
	b := builder.FinishedBytes()

	bd, _ := PrepareConf(b)
	out := bd.FinishedBytes()
	resp := pc.GetRootAsResp(out, 0)
	assert.Equal(t, uint32(1), resp.ConfToken())

	bd, _ = PrepareConf(b)
	out = bd.FinishedBytes()
	resp = pc.GetRootAsResp(out, 0)
	assert.Equal(t, uint32(2), resp.ConfToken())
}

func prepareConfWithData(builder *flatbuffers.Builder, arg ...flatbuffers.UOffsetT) {
	tes := []flatbuffers.UOffsetT{}
	for i := 0; i < len(arg); i += 2 {
		A6.TextEntryStart(builder)
		name := arg[i]
		value := arg[i+1]
		A6.TextEntryAddName(builder, name)
		A6.TextEntryAddValue(builder, value)
		te := A6.TextEntryEnd(builder)
		tes = append(tes, te)
	}

	pc.ReqStartConfVector(builder, len(tes))
	for i := len(tes) - 1; i >= 0; i-- {
		builder.PrependUOffsetT(tes[i])
	}
	v := builder.EndVector(len(tes))

	pc.ReqStart(builder)
	pc.ReqAddConf(builder, v)
	root := pc.ReqEnd(builder)
	builder.Finish(root)
	b := builder.FinishedBytes()

	PrepareConf(b)
}

func TestPrepareConfUnknownPlugin(t *testing.T) {
	InitConfCache(1 * time.Millisecond)
	builder := flatbuffers.NewBuilder(1024)

	name := builder.CreateString("xxx")
	value := builder.CreateString(`{"body":"yes"}`)
	prepareConfWithData(builder, name, value)
	res, _ := GetRuleConf(1)
	assert.Equal(t, 0, len(res))
}

func TestPrepareConfBadConf(t *testing.T) {
	InitConfCache(1 * time.Millisecond)
	builder := flatbuffers.NewBuilder(1024)

	f := func(in []byte) (conf interface{}, err error) {
		return nil, errors.New("ouch")
	}
	RegisterPlugin("bad_conf", f, emptyFilter)
	name := builder.CreateString("bad_conf")
	value := builder.CreateString(`{"body":"yes"}`)
	prepareConfWithData(builder, name, value)
	res, _ := GetRuleConf(1)
	assert.Equal(t, 0, len(res))
}

func TestPrepareConfConcurrently(t *testing.T) {
	InitConfCache(10 * time.Millisecond)

	builder := flatbuffers.NewBuilder(1024)
	pc.ReqStart(builder)
	root := pc.ReqEnd(builder)
	builder.Finish(root)
	b := builder.FinishedBytes()

	n := 10
	var wg sync.WaitGroup
	res := make([][]byte, n)
	for i := 0; i < n; i++ {
		wg.Add(1)
		go func(i int) {
			bd, err := PrepareConf(b)
			assert.Nil(t, err)
			res[i] = bd.FinishedBytes()[:]
			wg.Done()
		}(i)
	}
	wg.Wait()

	tokens := make([]int, n)
	for i := 0; i < n; i++ {
		resp := pc.GetRootAsResp(res[i], 0)
		tokens[i] = int(resp.ConfToken())
	}

	sort.Ints(tokens)
	for i := 0; i < n; i++ {
		assert.Equal(t, i+1, tokens[i])
	}
}

func TestGetRuleConf(t *testing.T) {
	InitConfCache(1 * time.Millisecond)
	builder := flatbuffers.NewBuilder(1024)
	pc.ReqStart(builder)
	root := pc.ReqEnd(builder)
	builder.Finish(root)
	b := builder.FinishedBytes()

	bd, _ := PrepareConf(b)
	out := bd.FinishedBytes()
	resp := pc.GetRootAsResp(out, 0)
	assert.Equal(t, uint32(1), resp.ConfToken())

	res, _ := GetRuleConf(1)
	assert.Equal(t, 0, len(res))

	time.Sleep(2 * time.Millisecond)
	_, err := GetRuleConf(1)
	assert.Equal(t, ttlcache.ErrNotFound, err)
}

func TestGetRuleConfCheckConf(t *testing.T) {
	RegisterPlugin("echo", emptyParseConf, emptyFilter)
	InitConfCache(1 * time.Millisecond)
	builder := flatbuffers.NewBuilder(1024)

	name := builder.CreateString("echo")
	value := builder.CreateString(`{"body":"yes"}`)
	A6.TextEntryStart(builder)
	A6.TextEntryAddName(builder, name)
	A6.TextEntryAddValue(builder, value)
	te := A6.TextEntryEnd(builder)

	pc.ReqStartConfVector(builder, 1)
	builder.PrependUOffsetT(te)
	v := builder.EndVector(1)

	pc.ReqStart(builder)
	pc.ReqAddConf(builder, v)
	root := pc.ReqEnd(builder)
	builder.Finish(root)
	b := builder.FinishedBytes()

	PrepareConf(b)
	res, _ := GetRuleConf(1)
	assert.Equal(t, 1, len(res))
	assert.Equal(t, "echo", res[0].Name)
}
