package api

import (
	"context"
	"errors"
	"time"

	ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd"
	nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/client"
)

// CreatePnd takes an address, a name and a description to create a new
// PrincipalNetworkDomain on the controller.
func CreatePnd(ctx context.Context, addr, name, description string) (*ppb.CreatePndListResponse, error) {
	pndClient, err := nbi.PndClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	req := &ppb.CreatePndListRequest{
		Timestamp: time.Now().UnixNano(),
		Pnd: []*ppb.PndCreateProperties{
			{
				Name:        name,
				Description: description,
			},
		},
	}

	return pndClient.CreatePndList(ctx, req)
}

// CreatePndList uses the provided creation properties to add all the PNDs to the controller.
func CreatePndList(ctx context.Context, addr string, pnds []*ppb.PndCreateProperties) (*ppb.CreatePndListResponse, error) {
	pndClient, err := nbi.PndClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	req := &ppb.CreatePndListRequest{
		Timestamp: time.Now().UnixNano(),
		Pnd:       pnds,
	}

	return pndClient.CreatePndList(ctx, req)
}

// GetPnd requests one PrincipalNetworkDomain from the
// controller.
func GetPnd(ctx context.Context, addr string, args string) (*ppb.GetPndResponse, error) {
	pndClient, err := nbi.PndClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}
	if len(args) <= 0 {
		return nil, errors.New("not enough arguments")
	}

	req := &ppb.GetPndRequest{
		Timestamp: time.Now().UnixNano(),
		Pid:       args,
	}
	return pndClient.GetPnd(ctx, req)
}

// GetPndList requests all PrincipalNetworkDomains from the
// controller.
func GetPndList(ctx context.Context, addr string, args ...string) (*ppb.GetPndListResponse, error) {
	pndClient, err := nbi.PndClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	req := &ppb.GetPndListRequest{
		Timestamp: time.Now().UnixNano(),
	}
	return pndClient.GetPndList(ctx, req)
}

// DeletePnd requests a deletion of the provided PND.
func DeletePnd(ctx context.Context, addr string, pid string) (*ppb.DeletePndResponse, error) {
	pndClient, err := nbi.PndClient(addr, dialOptions...)
	if err != nil {
		return nil, err
	}

	req := &ppb.DeletePndRequest{
		Timestamp: time.Now().UnixNano(),
		Pid:       pid,
	}
	return pndClient.DeletePnd(ctx, req)
}