package orm

import (
	"fmt"
	"net/http"
	"strings"

	"github.com/jinzhu/gorm"
	"gogs.carduccidante.edu.it/karmen/core/renderer"
)

type Operator struct {
	gorm.Model

	Lastname  string
	Firstname string
	Email     string

	Description string
}

func (o *Operator) GetID() uint { return o.ID }
func (o *Operator) String() string {
	return fmt.Sprintf("%s %s (%s)", strings.ToUpper(o.Lastname), strings.Title(o.Firstname), o.Description)
}

func (o *Operator) Create(args map[string]string, r *http.Request) (interface{}, error) {
	if r.Method == "GET" {
		operator := new(Operator)
		return operator, nil
	} else {
		operator := new(Operator)
		err := renderer.Decode(operator, r)
		if err != nil {
			return nil, err
		}
		operator, err = CreateOperator(operator)
		if err != nil {
			return nil, err
		}
		return operator, nil
	}
}

func (o *Operator) Read(args map[string]string, r *http.Request) (interface{}, error) {
	var operator Operator

	id := args["id"]

	if err := DB().Where("id = ?", id).Find(&operator).Error; err != nil {
		return nil, err
	}

	return &operator, nil
}

func (o *Operator) ReadAll(args map[string]string, r *http.Request) (interface{}, error) {
	var operators []*Operator

	if err := DB().Find(&operators).Error; err != nil {
		return nil, err
	}
	return operators, nil
}

func (o *Operator) Update(args map[string]string, r *http.Request) (interface{}, error) {
	if r.Method == "GET" {
		result, err := o.Read(args, r)
		if err != nil {
			return nil, err
		}

		operator := result.(*Operator)

		return operator, nil
	} else {
		operator, err := o.Read(args, r)
		if err != nil {
			return nil, err
		}

		err = renderer.Decode(operator, r)
		if err != nil {
			return nil, err
		}
		_, err = SaveOperator(operator)
		if err != nil {
			return nil, err
		}
		operator, err = o.Read(args, r)
		if err != nil {
			return nil, err
		}

		return operator.(*Operator), nil
	}
}

func (o *Operator) Delete(args map[string]string, r *http.Request) (interface{}, error) {
	operator, err := o.Read(args, r)
	if err != nil {
		return nil, err
	}
	if err := DB().Unscoped().Delete(operator.(*Operator)).Error; err != nil {
		return nil, err
	}
	return operator.(*Operator), nil
}

func SaveOperator(operator interface{}) (interface{}, error) {
	if err := DB().Save(operator).Error; err != nil {
		return nil, err
	}
	return operator, nil
}

func CreateOperator(operator *Operator) (*Operator, error) {
	if err := DB().Create(operator).Error; err != nil {
		return nil, err
	}
	return operator, nil
}
