# frozen_string_literal: true

require 'erb'
require 'json'
require 'date'

require_relative 'rspec_queries'
require_relative 'rspec_query'
require_relative 'merge_request'

class RspecHtml
  attr_reader :last_updated_at

  def initialize
    @last_updated_at = Time.now.utc
  end

  def write_html
    run_queries

    puts "creating #{html_filename}"
    File.write(html_filename, html)
  end

  def html
    template = File.join(File.dirname(__FILE__), 'templates/page.erb')
    ERB.new(File.read(template)).result(binding)
  end

  def html_filename
    'tmp/rspec/index.html'
  end

  def time_per_test
    overall_per_day do |_date, rows|
      time_per_test = rows.sum { |r| r['time_per_single_test'].to_f }
      total_rows = rows.size
      time_per_test / total_rows
    end
  end

  def queries_per_test
    overall_per_day do |_date, rows|
      total_queries = rows.sum { |r| r['total_queries'].to_f }
      number_of_tests = rows.sum { |r| r['number_of_tests'].to_f }
      total_queries / number_of_tests
    end
  end

  def visible_queries
    queries.reject(&:hidden?)
  end

  def queries
    @queries ||= SQL_QUERIES.map do |query|
      RspecQuery.new(query)
    end
  end

  def merge_requests_data
    # FIXME - a hacky way to get the first date we display
    # in per-day graphs, we need this to combine with list of MRs
    min_day = overall_data_by_day.keys.min

    all_mrs = MergeRequest.fetch(since: min_day)
    by_day = all_mrs.group_by(&:day)
    bars = by_day.map do |date, mrs|
      { x: date, y: mrs.size }
    end

    JSON.generate(bars)
  end

  private

  def run_queries
    queries.each do |query|
      query.write_csv
      query.write_json
    end
  end

  def overall_per_day
    chart_points = overall_data_by_day.map do |date, rows|
      y = yield date, rows
      y = 0 if y.nan?
      { x: date, y: y }
    end

    JSON.generate(chart_points)
  end

  def overall_data_by_day
    return @overall_data_by_day if @overall_data_by_day

    query = queries.find { |q| q.name == 'overall_time' }
    return '{}' unless query

    @overall_data_by_day = query.csv.group_by { |row| row['commit_date'] }
  end
end

RspecHtml.new.write_html
