/*
 * 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 iwrr

import (
	"math/rand"
	"sync"

	"dubbo.apache.org/dubbo-go/v3/cluster/loadbalance"
	"dubbo.apache.org/dubbo-go/v3/protocol"
)

type iwrrEntry struct {
	weight  int64
	invoker protocol.Invoker

	next *iwrrEntry
}

type iwrrQueue struct {
	head *iwrrEntry
	tail *iwrrEntry
}

func NewIwrrQueue() *iwrrQueue {
	return &iwrrQueue{}
}

func (item *iwrrQueue) push(entry *iwrrEntry) {
	entry.next = nil
	tail := item.tail
	item.tail = entry
	if tail == nil {
		item.head = entry
	} else {
		tail.next = entry
	}
}

func (item *iwrrQueue) pop() *iwrrEntry {
	head := item.head
	next := head.next
	head.next = nil
	item.head = next
	if next == nil {
		item.tail = nil
	}
	return head
}

func (item *iwrrQueue) empty() bool {
	return item.head == nil
}

// InterleavedweightedRoundRobin struct
type interleavedweightedRoundRobin struct {
	current *iwrrQueue
	next    *iwrrQueue
	step    int64
	mu      sync.Mutex
}

func NewInterleavedweightedRoundRobin(invokers []protocol.Invoker, invocation protocol.Invocation) *interleavedweightedRoundRobin {
	iwrrp := new(interleavedweightedRoundRobin)
	iwrrp.current = NewIwrrQueue()
	iwrrp.next = NewIwrrQueue()

	size := uint64(len(invokers))
	offset := rand.Uint64() % size
	step := int64(0)
	for idx := uint64(0); idx < size; idx++ {
		invoker := invokers[(idx+offset)%size]
		weight := loadbalance.GetWeight(invoker, invocation)
		step = gcdInt(step, weight)
		iwrrp.current.push(&iwrrEntry{
			invoker: invoker,
			weight:  weight,
		})
	}
	iwrrp.step = step

	return iwrrp
}

func (iwrr *interleavedweightedRoundRobin) Pick(invocation protocol.Invocation) protocol.Invoker {
	iwrr.mu.Lock()
	defer iwrr.mu.Unlock()

	if iwrr.current.empty() {
		iwrr.current, iwrr.next = iwrr.next, iwrr.current
	}

	entry := iwrr.current.pop()
	entry.weight -= iwrr.step

	if entry.weight > 0 {
		iwrr.current.push(entry)
	} else {
		weight := loadbalance.GetWeight(entry.invoker, invocation)
		if weight < 0 {
			weight = 0
		}
		entry.weight = weight
		iwrr.next.push(entry)
	}

	return entry.invoker
}

func gcdInt(a, b int64) int64 {
	for b != 0 {
		a, b = b, a%b
	}
	return a
}
