#!/usr/bin/env ruby

LKP_SRC = ENV['LKP_SRC'] || File.dirname(File.dirname(File.realpath($PROGRAM_NAME)))

require 'gnuplot'
require 'optparse'
require "#{LKP_SRC}/lib/statistics"
require "#{LKP_SRC}/lib/stats"
require "#{LKP_SRC}/lib/yaml"
require "#{LKP_SRC}/lib/plot"

opt_parser = OptionParser.new do |opts|
  opts.banner = 'Usage: mplot matrix.json [stat_fields...] [OPTION...]'
  opts.separator ''
  opts.separator 'Example:'
  opts.separator ''

  opts.separator 'mplot /result/fat/dd-write/1HDD-JBOD-cfq-btrfs-100dd/x86_64-rhel/matrix.json'
  opts.separator 'mplot /result/fat/dd-write/1HDD-JBOD-cfq-btrfs-100dd/x86_64-rhel/matrix.json vmstat.system.in'
  opts.separator ''
  opts.separator 'options:'

  opts.on('-o DIR', '--output DIR', 'output dir') do |dir|
    Dir.mkdir dir unless File.directory? dir
    $opt_output_path = dir
  end

  opts.on_tail('-h', '--help', 'show help message') do
    puts opts
    exit
  end
end

opt_parser.parse!(ARGV)

if ARGV.empty?
  puts opt_parser
  exit
end

# variation measured by values' (range : mean)
def stats_with_most_variation(matrix)
  stats = {}
  matrix.each do |field, values|
    next if values[-1].is_a?(String)
    next if field =~ /\.time$/
    next unless perf_metric? field

    mean, sorted = values.mean_sorted
    next if mean.zero?

    size = sorted.size
    margin = size >> MARGIN_SHIFT
    min = sorted[margin]
    max = sorted[-margin - 1]
    next unless reasonable_perf_change?(field, max, max)
    next if min == max
    next if sorted[0] == values[0] &&
            sorted[-1] == values[-1] &&
            sorted[size / 2] == values[size / 2]

    stats[field] = (max - min) / mean
  end
  Hash[stats.sort { |a, b| b[1] <=> a[1] }]
end

$matrix = load_json ARGV[0]

if ARGV[1]
  $stats = {}
  ARGV[1..-1].each { |stat| $stats[stat] = nil }
else
  $stats = stats_with_most_variation $matrix
end

mplot $matrix, $stats
