/*
 * Copyright 2018-present Open Networking Foundation

 * 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

 * 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 group

import (
	"context"
	"fmt"
	"sync"

	"github.com/opencord/voltha-go/db/model"
	"github.com/opencord/voltha-lib-go/v3/pkg/log"
	ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// Loader hides all low-level locking & synchronization related to group state updates
type Loader struct {
	// this lock protects the groups map, it does not protect individual groups
	lock   sync.RWMutex
	groups map[uint32]*chunk

	dbProxy *model.Proxy
}

// chunk keeps a group and the lock for this group
type chunk struct {
	// this lock is used to synchronize all access to the group, and also to the "deleted" variable
	lock    sync.Mutex
	deleted bool

	group *ofp.OfpGroupEntry
}

func NewLoader(dbProxy *model.Proxy) *Loader {
	return &Loader{
		groups:  make(map[uint32]*chunk),
		dbProxy: dbProxy,
	}
}

// Load queries existing groups from the kv,
// and should only be called once when first created.
func (loader *Loader) Load(ctx context.Context) {
	loader.lock.Lock()
	defer loader.lock.Unlock()

	var groups []*ofp.OfpGroupEntry
	if err := loader.dbProxy.List(ctx, &groups); err != nil {
		logger.Errorw("failed-to-list-groups-from-cluster-data-proxy", log.Fields{"error": err})
		return
	}
	for _, group := range groups {
		loader.groups[group.Desc.GroupId] = &chunk{group: group}
	}
}

// LockOrCreate locks this group if it exists, or creates a new group if it does not.
// In the case of group creation, the provided "group" must not be modified afterwards.
func (loader *Loader) LockOrCreate(ctx context.Context, group *ofp.OfpGroupEntry) (*Handle, bool, error) {
	// try to use read lock instead of full lock if possible
	if handle, have := loader.Lock(group.Desc.GroupId); have {
		return handle, false, nil
	}

	loader.lock.Lock()
	entry, have := loader.groups[group.Desc.GroupId]
	if !have {
		entry := &chunk{group: group}
		loader.groups[group.Desc.GroupId] = entry
		entry.lock.Lock()
		loader.lock.Unlock()

		if err := loader.dbProxy.Set(ctx, fmt.Sprint(group.Desc.GroupId), group); err != nil {
			logger.Errorw("failed-adding-group-to-db", log.Fields{"groupID": group.Desc.GroupId, "err": err})

			// revert the map
			loader.lock.Lock()
			delete(loader.groups, group.Desc.GroupId)
			loader.lock.Unlock()

			entry.deleted = true
			entry.lock.Unlock()
			return nil, false, err
		}
		return &Handle{loader: loader, chunk: entry}, true, nil
	}
	loader.lock.Unlock()

	entry.lock.Lock()
	if entry.deleted {
		entry.lock.Unlock()
		return loader.LockOrCreate(ctx, group)
	}
	return &Handle{loader: loader, chunk: entry}, false, nil
}

// Lock acquires the lock for this group, and returns a handle which can be used to access the group until it's unlocked.
// This handle ensures that the group cannot be accessed if the lock is not held.
// Returns false if the group is not present.
// TODO: consider accepting a ctx and aborting the lock attempt on cancellation
func (loader *Loader) Lock(id uint32) (*Handle, bool) {
	loader.lock.RLock()
	entry, have := loader.groups[id]
	loader.lock.RUnlock()

	if !have {
		return nil, false
	}

	entry.lock.Lock()
	if entry.deleted {
		entry.lock.Unlock()
		return loader.Lock(id)
	}
	return &Handle{loader: loader, chunk: entry}, true
}

type Handle struct {
	loader *Loader
	chunk  *chunk
}

// GetReadOnly returns an *ofp.OfpGroupEntry which MUST NOT be modified externally, but which is safe to keep indefinitely
func (h *Handle) GetReadOnly() *ofp.OfpGroupEntry {
	return h.chunk.group
}

// Update updates an existing group in the kv.
// The provided "group" must not be modified afterwards.
func (h *Handle) Update(ctx context.Context, group *ofp.OfpGroupEntry) error {
	if err := h.loader.dbProxy.Set(ctx, fmt.Sprint(group.Desc.GroupId), group); err != nil {
		return status.Errorf(codes.Internal, "failed-update-group-%v: %s", group.Desc.GroupId, err)
	}
	h.chunk.group = group
	return nil
}

// Delete removes the device from the kv
func (h *Handle) Delete(ctx context.Context) error {
	if err := h.loader.dbProxy.Remove(ctx, fmt.Sprint(h.chunk.group.Desc.GroupId)); err != nil {
		return fmt.Errorf("couldnt-delete-group-from-store-%v", h.chunk.group.Desc.GroupId)
	}
	h.chunk.deleted = true

	h.loader.lock.Lock()
	delete(h.loader.groups, h.chunk.group.Desc.GroupId)
	h.loader.lock.Unlock()

	h.Unlock()
	return nil
}

// Unlock releases the lock on the group
func (h *Handle) Unlock() {
	if h.chunk != nil {
		h.chunk.lock.Unlock()
		h.chunk = nil // attempting to access the group through this handle in future will panic
	}
}

// List returns a snapshot of all the managed group IDs
// TODO: iterating through groups safely is expensive now, since all groups are stored & locked separately
//       should avoid this where possible
func (loader *Loader) List() map[uint32]struct{} {
	loader.lock.RLock()
	defer loader.lock.RUnlock()
	// copy the IDs so caller can safely iterate
	ret := make(map[uint32]struct{}, len(loader.groups))
	for id := range loader.groups {
		ret[id] = struct{}{}
	}
	return ret
}
