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

import (
	"context"
	"fmt"
	"sync"

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

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

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

	port *voltha.Port
}

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

// Load queries existing ports 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 ports []*voltha.Port
	if err := loader.dbProxy.List(ctx, &ports); err != nil {
		logger.Errorw(ctx, "failed-to-list-ports-from-cluster-data-proxy", log.Fields{"error": err})
		return
	}
	for _, port := range ports {
		loader.ports[port.PortNo] = &chunk{port: port}
	}
}

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

	loader.lock.Lock()
	entry, have := loader.ports[port.PortNo]
	if !have {
		entry := &chunk{port: port}
		loader.ports[port.PortNo] = entry
		entry.lock.Lock()
		loader.lock.Unlock()

		if err := loader.dbProxy.Set(ctx, fmt.Sprint(port.PortNo), port); err != nil {
			// revert the map
			loader.lock.Lock()
			delete(loader.ports, port.PortNo)
			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, port)
	}
	return &Handle{loader: loader, chunk: entry}, false, nil
}

// Lock acquires the lock for this port, and returns a handle which can be used to access the port until it's unlocked.
// This handle ensures that the port cannot be accessed if the lock is not held.
// Returns false if the port 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.ports[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
}

// Handle is allocated for each Lock() call, all modifications are made using it, and it is invalidated by Unlock()
// This enforces correct Lock()-Usage()-Unlock() ordering.
type Handle struct {
	loader *Loader
	chunk  *chunk
}

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

// Update updates an existing port in the kv.
// The provided "port" must not be modified afterwards.
func (h *Handle) Update(ctx context.Context, port *voltha.Port) error {
	if err := h.loader.dbProxy.Set(ctx, fmt.Sprint(port.PortNo), port); err != nil {
		return status.Errorf(codes.Internal, "failed-update-port-%v: %s", port.PortNo, err)
	}
	h.chunk.port = port
	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.port.PortNo)); err != nil {
		return fmt.Errorf("couldnt-delete-port-from-store-%v", h.chunk.port.PortNo)
	}
	h.chunk.deleted = true

	h.loader.lock.Lock()
	delete(h.loader.ports, h.chunk.port.PortNo)
	h.loader.lock.Unlock()

	h.Unlock()
	return nil
}

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

// ListIDs returns a snapshot of all the managed port IDs
// TODO: iterating through ports safely is expensive now, since all ports are stored & locked separately
//       should avoid this where possible
func (loader *Loader) ListIDs() 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.ports))
	for id := range loader.ports {
		ret[id] = struct{}{}
	}
	return ret
}
