require 'lib/id_map'

class Puzzle < IDMap
  def initialize(id=nil)
    @table = "Puzzles"
    super(@table, id)

    add_metadata()
  end

  def from_row(row)
    super(row)
    add_metadata()

    return self
  end

  def add_metadata
    return if !get("rating").nil?

    # Try to annotate with computed attributes
    set("rating", 0)
    set("fails", 0)
    set("mean_attempts", 0)
    set("wins", 0)
    set("author_u", "unknown")
    set("author", "unknown")
    begin
      set("wins", get("positive_ratings") + get("negative_ratings"))
      set("fails", get("attempts") - get("wins"))
      set("mean_attempts", get("attempts").to_f / get("wins"))
      set("rating", get("positive_ratings").to_f / (get("positive_ratings") + get("negative_ratings")))

      %w{wins fails mean_attempts rating}.each { |x| set(x, 0) if get(x).to_f.nan? }
    rescue
      # puts $!
      # puts $!.backtrace.join("\n")
      # Nae worries, we just don't have metadata
    end

    # Try to find the creator's name
    begin
      author = SQLWrapper.select("Users", get('creator'))
      set("author", author['alias'])
      set("author_u", author['uniquename'])
    rescue
      set("author", "Unknown")
      set("author_u", "Unknown")
    end
  end

  def rate(positive=true)
    db = SQLWrapper.new
    ratings = positive ? "positive_ratings" : "negative_ratings"
    db.query("UPDATE #{@table} set #{ratings} = #{ratings}+1 where id=#{@id}")
    db.close
  end

  def attempt(delta=1)
    db = SQLWrapper.new
    db.query("UPDATE #{@table} set attempts = attempts + #{delta} where id=#{@id}")
    db.close
  end

  def self.create(user, json)
    db = SQLWrapper.new
    begin
      db.insert("Puzzles", {
        "creator" => "#{user.id}",
        "json" => db.quote(json)
      })

      puzzle = Puzzle.new(db.last_id)
      db.close
      return puzzle
    rescue
      return nil
    end
  end

  def self.random
    self.fetch("SELECT id FROM Puzzles where active = 1 order by rand() limit 1")
  end

  def self.curated
    self.fetch("SELECT id FROM Puzzles where curated = 1 order by rand() limit 1")
  end

  def self.fetch(sql)
    db = SQLWrapper.new
    rows = db.rows(sql)
    puzzle = Puzzle.new(rows[0]['id'])
    db.close
    return puzzle
  end
end
