package api

import (
	"context"
	"time"

	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
	nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
	"github.com/google/uuid"
)

// CreateRoles creates roles with provided data.
func CreateRoles(ctx context.Context, addr string, roles []*apb.Role) (*apb.CreateRolesResponse, error) {
	roleClient, err := nbi.RoleClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	r := &apb.CreateRolesRequest{
		Timestamp: time.Now().UnixNano(),
		Roles:     roles,
	}

	return roleClient.CreateRoles(ctx, r)
}

// GetRole returns one requested role found by name.
func GetRole(ctx context.Context, addr, name string, uuid uuid.UUID) (*apb.GetRoleResponse, error) {
	roleClient, err := nbi.RoleClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	r := &apb.GetRoleRequest{
		Timestamp: time.Now().UnixNano(),
		RoleName:  name,
		Id:        uuid.String(),
	}

	return roleClient.GetRole(ctx, r)
}

// GetRoles returns all available roles.
func GetRoles(ctx context.Context, addr string) (*apb.GetRolesResponse, error) {
	roleClient, err := nbi.RoleClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	r := &apb.GetRolesRequest{
		Timestamp: time.Now().UnixNano(),
	}

	return roleClient.GetRoles(ctx, r)
}

// UpdateRoles updates the procided roles.
func UpdateRoles(ctx context.Context, addr string, roles []*apb.Role) (*apb.UpdateRolesResponse, error) {
	roleClient, err := nbi.RoleClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	r := &apb.UpdateRolesRequest{
		Timestamp: time.Now().UnixNano(),
		Roles:     roles,
	}

	return roleClient.UpdateRoles(ctx, r)
}

// DeletePermissionForRole deletes the provided permissions from one role found by name.
func DeletePermissionForRole(ctx context.Context, addr, name string, permissionsToDelete []string) (*apb.DeletePermissionsForRoleResponse, error) {
	roleClient, err := nbi.RoleClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	r := &apb.DeletePermissionsForRoleRequest{
		Timestamp:           time.Now().UnixNano(),
		RoleName:            name,
		PermissionsToDelete: permissionsToDelete,
	}

	return roleClient.DeletePermissionsForRole(ctx, r)
}

// DeleteRoles deletes all the provided roles with their permissions.
func DeleteRoles(ctx context.Context, addr string, roleName []string) (*apb.DeleteRolesResponse, error) {
	roleClient, err := nbi.RoleClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	r := &apb.DeleteRolesRequest{
		Timestamp: time.Now().UnixNano(),
		RoleName:  roleName,
	}

	return roleClient.DeleteRoles(ctx, r)
}
