package controller

import (
	"fmt"

	"github.com/jinzhu/gorm"
	"github.com/pingcap/tep/db/entity"
	"github.com/pingcap/tep/pkg/apis/apiserver"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
)

func (c *Controller) GetNodeList(opts metav1.ListOptions) (*corev1.NodeList, error) {
	return c.kubeCli.CoreV1().Nodes().List(opts)
}

func (c *Controller) GetNode(name string) (*corev1.Node, error) {
	return c.kubeCli.CoreV1().Nodes().Get(name, metav1.GetOptions{})
}

func (c *Controller) UpdateNode(node *corev1.Node) (*corev1.Node, error) {
	return c.kubeCli.CoreV1().Nodes().Update(node)
}

func (c *Controller) AssembleMachine(machine *entity.Machine) *apiserver.Machine {
	return &apiserver.Machine{
		ObjectMeta: metav1.ObjectMeta{
			Name:              machine.ID,
			UID:               types.UID(machine.ID),
			CreationTimestamp: metav1.NewTime(machine.CreatedAt),
		},
		IP:       machine.IP,
		Hostname: machine.Hostname,
		Status:   machine.Status,
		OS:       machine.OS,
		Kernel:   machine.Kernel,
		CPUCores: machine.CPUCores,
		Memory:   machine.Memory,
		NIC:      machine.NIC,
		Rack:     machine.Rack,
		Purpose:  machine.Purpose,
	}
}

func (c *Controller) AssembleMachineEntity(machine *apiserver.Machine) *entity.Machine {
	return &entity.Machine{
		ID:       machine.Name,
		IP:       machine.IP,
		Hostname: machine.Hostname,
		Status:   machine.Status,
		OS:       machine.OS,
		Kernel:   machine.Kernel,
		CPUCores: machine.CPUCores,
		Memory:   machine.Memory,
		NIC:      machine.NIC,
		Rack:     machine.Rack,
		Purpose:  machine.Purpose,
	}
}

func (c *Controller) GetAzByName(name string, db *gorm.DB) (*entity.Az, error) {
	az := &entity.Az{}
	if err := db.Where("name = ?", name).First(az).Error; err != nil {
		if gorm.IsRecordNotFoundError(err) {
			errMsg := fmt.Errorf("az with name[%s] was not found in the az table", name)
			return nil, errMsg
		}

		errMsg := fmt.Errorf("failed to query az table with error[%v]", err)
		return nil, errMsg
	}
	return az, nil
}

func (c *Controller) GetAzByID(id uint, db *gorm.DB) (*entity.Az, error) {
	az := &entity.Az{}
	if err := db.Where("id = ?", id).First(az).Error; err != nil {
		if gorm.IsRecordNotFoundError(err) {
			errMsg := fmt.Errorf("az with id[%d] was not found in the az table", id)
			return nil, errMsg
		}

		errMsg := fmt.Errorf("failed to query az table with error[%v]", err)
		return nil, errMsg
	}
	return az, nil
}
