package fic

import ()

// FlagChoice represents a choice a respond to a classic flag
type FlagChoice struct {
	Id int `json:"id"`
	// IdFlag is the identifier of the underlying flag
	IdFlag int `json:"idFlag"`
	// Label is the title of the choice as displayed to players
	Label string `json:"label"`
	// Value is the raw content that'll be written as response if this choice is selected
	Value string `json:"value"`
}

// GetChoices returns a list of choices for the given Flag.
func (f *FlagKey) GetChoices() ([]*FlagChoice, error) {
	if rows, err := DBQuery("SELECT id_choice, id_flag, label, response FROM flag_choices WHERE id_flag = ?", f.Id); err != nil {
		return nil, err
	} else {
		defer rows.Close()

		var choices []*FlagChoice
		for rows.Next() {
			c := &FlagChoice{}
			c.IdFlag = f.Id

			if err := rows.Scan(&c.Id, &c.IdFlag, &c.Label, &c.Value); err != nil {
				return nil, err
			}

			choices = append(choices, c)
		}
		if err := rows.Err(); err != nil {
			return nil, err
		}

		return choices, nil
	}
}

// GetChoice returns a choice for the given Flag.
func (f *FlagKey) GetChoice(id int) (c *FlagChoice, err error) {
	c = &FlagChoice{}
	if errr := DBQueryRow("SELECT id_choice, id_flag, label, response FROM flag_choices WHERE id_choice = ?", id).Scan(&c.Id, &c.IdFlag, &c.Label, &c.Value); errr != nil {
		return c, errr
	}
	return
}

// AddChoice creates and fills a new struct FlagChoice, from a label and a value.
func (f *FlagKey) AddChoice(c *FlagChoice) (*FlagChoice, error) {
	if res, err := DBExec("INSERT INTO flag_choices (id_flag, label, response) VALUES (?, ?, ?)", f.Id, c.Label, c.Value); err != nil {
		return c, err
	} else {
		cid, err := res.LastInsertId()
		c.Id = int(cid)
		return c, err
	}
}

// Update applies modifications back to the database.
func (c *FlagChoice) Update() (int64, error) {
	if res, err := DBExec("UPDATE flag_choices SET id_flag = ?, label = ?, response = ? WHERE id_choice = ?", c.IdFlag, c.Label, c.Value, c.Id); err != nil {
		return 0, err
	} else if nb, err := res.RowsAffected(); err != nil {
		return 0, err
	} else {
		return nb, err
	}
}

// Delete the flag from the database.
func (c *FlagChoice) Delete() (int64, error) {
	if res, err := DBExec("DELETE FROM flag_choices WHERE id_choice = ?", c.Id); err != nil {
		return 0, err
	} else if nb, err := res.RowsAffected(); err != nil {
		return 0, err
	} else {
		return nb, err
	}
}

// WipeFlags deletes flags coming with the challenge.
func (f *FlagKey) WipeChoices() (int64, error) {
	if res, err := DBExec("DELETE FROM flag_choices WHERE id_flag = ?", f.Id); err != nil {
		return 0, err
	} else if nb, err := res.RowsAffected(); err != nil {
		return 0, err
	} else {
		return nb, err
	}
}
