package models

import (
	"errors"
	"log"
)

type Role struct {
	RoleId    int    `db:"RoleId"`
	RoleName  string `db:"RoleName"`
	LdapGroup string `db:"LdapGroup"`
	ReadOnly  bool   `db:"ReadOnly"`
	Admin     bool   `db:"Admin"`
}

func QueryRoles() ([]Role, error) {
	var results []Role

	// Query database for role definitions
	rows, err := db.Queryx("SELECT * FROM roles")

	if err != nil {
		log.Printf("QueryRoles error executing sql record : '%s'\n", err)
		return results, err
	} else {
		// parse all the results into a slice
		for rows.Next() {
			var r Role
			err = rows.StructScan(&r)
			if err != nil {
				log.Printf("QueryRoles error parsing sql record : '%s'\n", err)
				return results, err
			}
			results = append(results, r)

		}
		log.Printf("QueryRoles retrieved '%d' results\n", len(results))
	}

	return results, nil
}

// AddRole adds a new role definition to the database
func (r *Role) AddRole() (*Role, error) {
	var err error

	// Validate role not already in use
	_, err = GetRoleByName(r.RoleName)

	// TODO

	if err != nil && err.Error() == "role not found" {
		log.Printf("AddRole confirmed no existing role, continuing with creation of role '%s'\n", r.RoleName)

		result, err := db.NamedExec(("INSERT INTO roles (RoleName, ReadOnly, Admin, LdapGroup) VALUES (:RoleName, :ReadOnly, :Admin, :LdapGroup);"), r)

		if err != nil {
			log.Printf("AddRole error executing sql record : '%s'\n", err)
			return &Role{}, err
		} else {
			affected, _ := result.RowsAffected()
			id, _ := result.LastInsertId()
			log.Printf("AddRole insert returned result id '%d' affecting %d row(s).\n", id, affected)
		}
	} else {
		log.Printf("AddRole RoleName already exists : '%v'\n", err)
	}

	return r, nil
}

func GetRoleByName(rolename string) (Role, error) {

	var r Role

	// Query database for matching user object
	err := db.QueryRowx("SELECT * FROM roles WHERE RoleName=?", rolename).StructScan(&r)
	if err != nil {
		return r, errors.New("role not found")
	}

	return r, nil
}
