package models

import (
	"database/sql"
	"time"

	pb "git.unistack.org/unistack-org/pkgdash/proto"
	"google.golang.org/protobuf/types/known/timestamppb"
)

type Handler struct {
	ID       uint64          `db:"id"`
	Package  uint64          `db:"package"`
	Name     string          `db:"name"`
	Coverage sql.NullFloat64 `db:"coverage"`
}

func NewHandler(hdlr *Handler) *pb.Handler {
	if hdlr == nil {
		return nil
	}
	rsp := &pb.Handler{
		Id:      hdlr.ID,
		Package: hdlr.Package,
		Name:    hdlr.Name,
	}
	if hdlr.Coverage.Valid {
		rsp.Coverage = hdlr.Coverage.Float64
	}
	return rsp
}

type Package struct {
	Created     time.Time       `db:"created"`
	Updated     time.Time       `db:"updated"`
	LastCheck   sql.NullTime    `db:"last_check"`
	Type        string          `db:"type"`
	Name        string          `db:"name"`
	URL         string          `db:"url"`
	Description sql.NullString  `db:"description"`
	Coverage    sql.NullFloat64 `db:"coverage"`
	Modules     uint64          `db:"modules"`
	ID          uint64          `db:"id"`
	Status      uint64          `db:"status"`
	Comments    uint64          `db:"comments"`
	Issues      uint64          `db:"issues"`
}

func NewPackage(pkg *Package) *pb.Package {
	if pkg == nil {
		return nil
	}
	rsp := &pb.Package{
		Name:     pkg.Name,
		Url:      pkg.URL,
		Modules:  pkg.Modules,
		Issues:   pkg.Issues,
		Comments: pkg.Comments,
		Id:       pkg.ID,
		Created:  timestamppb.New(pkg.Created),
		Updated:  timestamppb.New(pkg.Updated),
		Type:     pkg.Type,
	}
	if rsp.Type == "" {
		rsp.Type = "package"
	}
	if pkg.Description.Valid {
		rsp.Description = pkg.Description.String
	}
	if pkg.LastCheck.Valid {
		rsp.LastCheck = timestamppb.New(pkg.LastCheck.Time)
	}
	if pkg.Coverage.Valid {
		rsp.Coverage = pkg.Coverage.Float64
	}
	return rsp
}

type Module struct {
	LastCheck sql.NullTime `db:"last_check"`
	Name      string       `db:"name"`
	Version   string       `db:"version"`
	ID        uint64       `db:"id"`
}

func NewModule(mod *Module) *pb.Module {
	if mod == nil {
		return nil
	}
	rsp := &pb.Module{
		Name:    mod.Name,
		Version: mod.Version,
		Id:      mod.ID,
	}
	if mod.LastCheck.Valid {
		rsp.LastCheck = timestamppb.New(mod.LastCheck.Time)
	}
	return rsp
}

type Issue struct {
	Comment string  `db:"comment"`
	Modules []int64 `db:"modules"`
	ID      uint64  `db:"id"`
	Status  uint64  `db:"status"`
	Package uint64  `db:"package"`
}

type Comment struct {
	Created time.Time `db:"created"`
	Updated time.Time `db:"updated"`
	Comment string    `db:"comment"`
	ID      uint64    `db:"id"`
}

func NewComment(com *Comment) *pb.Comment {
	if com == nil {
		return nil
	}
	return &pb.Comment{
		Id:      com.ID,
		Comment: com.Comment,
		Created: timestamppb.New(com.Created),
		Updated: timestamppb.New(com.Updated),
	}
}
