// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace StatsViewer {
  public partial class StatsViewer : Form  {
    /// <summary>
    /// Create a StatsViewer.
    /// </summary>
    public StatsViewer() {
      InitializeComponent();
    }

    #region Protected Methods
    /// <summary>
    /// Callback when the form loads.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnLoad(EventArgs e) {
      base.OnLoad(e);

      timer_ = new Timer();
      timer_.Interval = kPollInterval;
      timer_.Tick += new EventHandler(PollTimerTicked);
      timer_.Start();
    }
    #endregion

    #region Private Methods
    /// <summary>
    /// Attempt to open the stats file.
    /// Return true on success, false otherwise.
    /// </summary>
    private bool OpenStatsFile() {
      StatsTable table = new StatsTable();
      if (table.Open(kStatsTableName)) {
        stats_table_ = table;
        return true;
      }
      return false;
    }

    /// <summary>
    /// Close the open stats file.
    /// </summary>
    private void CloseStatsFile() {
      if (this.stats_table_ != null)
      {
        this.stats_table_.Close();
        this.stats_table_ = null;
        this.listViewCounters.Items.Clear();
      }
    }

    /// <summary>
    /// Updates the process list in the UI.
    /// </summary>
    private void UpdateProcessList() {
      int current_pids = comboBoxFilter.Items.Count;
      int table_pids = stats_table_.Processes.Count;
      if (current_pids != table_pids + 1)  // Add one because of the "all" entry.
      {
        int selected_index = this.comboBoxFilter.SelectedIndex;
        this.comboBoxFilter.Items.Clear();
        this.comboBoxFilter.Items.Add(kStringAllProcesses);
        foreach (int pid in stats_table_.Processes)
          this.comboBoxFilter.Items.Add(kStringProcess + pid.ToString());
        this.comboBoxFilter.SelectedIndex = selected_index;
      }
    }

    /// <summary>
    /// Updates the UI for a counter.
    /// </summary>
    /// <param name="counter"></param>
    private void UpdateCounter(IStatsCounter counter) {
      ListView view;

      // Figure out which list this counter goes into.
      if (counter is StatsCounterRate)
        view = listViewRates;
      else if (counter is StatsCounter || counter is StatsTimer)
        view = listViewCounters;
      else
        return; // Counter type not supported yet.

      // See if the counter is already in the list.
      ListViewItem item = view.Items[counter.name];
      if (item != null)
      {
        // Update an existing counter.
        Debug.Assert(item is StatsCounterListViewItem);
        StatsCounterListViewItem counter_item = item as StatsCounterListViewItem;
        counter_item.Update(counter, filter_pid_);
      }
      else
      {
        // Create a new counter
        StatsCounterListViewItem new_item = null;
        if (counter is StatsCounterRate)
          new_item = new RateListViewItem(counter, filter_pid_);
        else if (counter is StatsCounter || counter is StatsTimer)
          new_item = new CounterListViewItem(counter, filter_pid_);
        Debug.Assert(new_item != null);
        view.Items.Add(new_item);
      }
    }

    /// <summary>
    /// Sample the data and update the UI
    /// </summary>
    private void SampleData() {
      // If the table isn't open, try to open it again.
      if (stats_table_ == null)
        if (!OpenStatsFile())
          return;

      if (stats_counters_ == null)
        stats_counters_ = stats_table_.Counters();

      if (pause_updates_)
        return;

      stats_counters_.Update();

      UpdateProcessList();

      foreach (IStatsCounter counter in stats_counters_)
        UpdateCounter(counter);
    }

    /// <summary>
    /// Set the background color based on the value
    /// </summary>
    /// <param name="item"></param>
    /// <param name="value"></param>
    private void ColorItem(ListViewItem item, int value)
    {
      if (value < 0)
        item.ForeColor = Color.Red;
      else if (value > 0)
        item.ForeColor = Color.DarkGreen;
      else
        item.ForeColor = Color.Black;
    }

    /// <summary>
    /// Called when the timer fires.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void PollTimerTicked(object sender, EventArgs e) {
      SampleData();
    }

    /// <summary>
    /// Called when the interval is changed by the user.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void interval_changed(object sender, EventArgs e) {
      int interval = 1;
      if (int.TryParse(comboBoxInterval.Text, out interval)) {
        if (timer_ != null) {
          timer_.Stop();
          timer_.Interval = interval * 1000;
          timer_.Start();
        }
      } else {
        comboBoxInterval.Text = timer_.Interval.ToString();
      }
    }

    /// <summary>
    /// Called when the user changes the filter
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void filter_changed(object sender, EventArgs e) {
      // While in this event handler, don't allow recursive events!
      this.comboBoxFilter.SelectedIndexChanged -= new System.EventHandler(this.filter_changed);
      if (this.comboBoxFilter.Text == kStringAllProcesses)
        filter_pid_ = 0;
      else
        int.TryParse(comboBoxFilter.Text.Substring(kStringProcess.Length), out filter_pid_);
      SampleData();
      this.comboBoxFilter.SelectedIndexChanged += new System.EventHandler(this.filter_changed);
    }

    /// <summary>
    /// Callback when the mouse enters a control
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void mouse_Enter(object sender, EventArgs e) {
      // When the dropdown is expanded, we pause 
      // updates, as it messes with the UI.
      pause_updates_ = true;
    }

    /// <summary>
    /// Callback when the mouse leaves a control
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void mouse_Leave(object sender, EventArgs e) {
      pause_updates_ = false;
    }

    /// <summary>
    /// Called when the user clicks the zero-stats button.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonZero_Click(object sender, EventArgs e) {
      this.stats_table_.Zero();
      SampleData();
    }

    /// <summary>
    /// Called when the user clicks a column heading.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void column_Click(object sender, ColumnClickEventArgs e) {
      if (e.Column != sort_column_) {
        sort_column_ = e.Column;
        this.listViewCounters.Sorting = SortOrder.Ascending;
      } else {
        if (this.listViewCounters.Sorting == SortOrder.Ascending)
          this.listViewCounters.Sorting = SortOrder.Descending;
        else
          this.listViewCounters.Sorting = SortOrder.Ascending;
      }

      this.listViewCounters.ListViewItemSorter =
          new ListViewItemComparer(e.Column, this.listViewCounters.Sorting);
      this.listViewCounters.Sort();
    }

    /// <summary>
    /// Called when the user clicks the button "Export".
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonExport_Click(object sender, EventArgs e) {
      //Have to pick a textfile to export to.
      //Saves what is shown in listViewStats in the format: function   value
      //(with a tab in between), so that it is easy to copy paste into a spreadsheet.
      //(Does not save the delta values.)
      TextWriter tw = null;
      try {
        saveFileDialogExport.CheckFileExists = false;
        saveFileDialogExport.ShowDialog();
        tw = new StreamWriter(saveFileDialogExport.FileName);

        for (int i = 0; i < listViewCounters.Items.Count; i++) {
          tw.Write(listViewCounters.Items[i].SubItems[0].Text + "\t");
          tw.WriteLine(listViewCounters.Items[i].SubItems[1].Text);
        }
      }
      catch (IOException ex) {
        MessageBox.Show(string.Format("There was an error while saving your results file. The results might not have been saved correctly.: {0}", ex.Message));
      } 
      finally{
        if (tw != null) tw.Close();
      }
    }

    #endregion

    class ListViewItemComparer : IComparer {
      public ListViewItemComparer() {
        this.col_ = 0;
        this.order_ = SortOrder.Ascending;
      }

      public ListViewItemComparer(int column, SortOrder order) {
        this.col_ = column;
        this.order_ = order;
      }

      public int Compare(object x, object y) {
        int return_value = -1;

        object x_tag = ((ListViewItem)x).SubItems[col_].Tag;
        object y_tag = ((ListViewItem)y).SubItems[col_].Tag;

        if (Comparable(x_tag, y_tag))
          return_value = ((IComparable)x_tag).CompareTo(y_tag);
        else
          return_value = String.Compare(((ListViewItem)x).SubItems[col_].Text,
              ((ListViewItem)y).SubItems[col_].Text);

        if (order_ == SortOrder.Descending)
          return_value *= -1;

        return return_value;
      }

      #region Private Methods
      private bool Comparable(object x, object y) {
        if (x == null || y == null)
          return false;

        return x is IComparable && y is IComparable;
      }
      #endregion

      #region Private Members
      private int col_;
      private SortOrder order_;
      #endregion
    }

    #region Private Members
    private const string kStringAllProcesses = "All Processes";
    private const string kStringProcess = "Process ";
    private const int kPollInterval = 1000;  // 1 second
    private const string kStatsTableName = "ChromeStats";
    private StatsTable stats_table_;
    private StatsTableCounters stats_counters_;
    private Timer timer_;
    private int filter_pid_;
    private bool pause_updates_;
    private int sort_column_ = -1;
    #endregion

    #region Private Event Callbacks
    private void openToolStripMenuItem_Click(object sender, EventArgs e)
    {
      OpenDialog dialog = new OpenDialog();
      dialog.ShowDialog();

      CloseStatsFile();

      StatsTable table = new StatsTable();
      bool rv = table.Open(dialog.FileName);
      if (!rv)
      {
        MessageBox.Show("Could not open statsfile: " + dialog.FileName);
      }
      else
      {
        stats_table_ = table;
      }
    }

    private void closeToolStripMenuItem_Click(object sender, EventArgs e)
    {
      CloseStatsFile();
    }

    private void quitToolStripMenuItem_Click(object sender, EventArgs e)
    {
      Application.Exit();
    }
    #endregion
  }

  /// <summary>
  /// Base class for counter list view items.
  /// </summary>
  internal class StatsCounterListViewItem : ListViewItem
  {
    /// <summary>
    /// Create the ListViewItem
    /// </summary>
    /// <param name="text"></param>
    public StatsCounterListViewItem(string text) : base(text) { }

    /// <summary>
    /// Update the ListViewItem given a new counter value.
    /// </summary>
    /// <param name="counter"></param>
    /// <param name="filter_pid"></param>
    public virtual void Update(IStatsCounter counter, int filter_pid) { }

    /// <summary>
    /// Set the background color based on the value
    /// </summary>
    /// <param name="value"></param>
    protected void ColorItem(int value)
    {
      if (value < 0)
        ForeColor = Color.Red;
      else if (value > 0)
        ForeColor = Color.DarkGreen;
      else
        ForeColor = Color.Black;
    }

    /// <summary>
    /// Create a new subitem with a zeroed Tag.
    /// </summary>
    /// <returns></returns>
    protected ListViewSubItem NewSubItem()
    {
      ListViewSubItem item = new ListViewSubItem();
      item.Tag = -1;  // Arbitrarily initialize to -1.
      return item;
    }

    /// <summary>
    /// Set the value for a subitem.
    /// </summary>
    /// <param name="item"></param>
    /// <param name="val"></param>
    /// <returns>True if the value changed, false otherwise</returns>
    protected bool SetSubItem(ListViewSubItem item, int val)
    {
      // The reason for doing this extra compare is because 
      // we introduce flicker if we unnecessarily update the 
      // subitems.  The UI is much less likely to cause you
      // a seizure when we do this.
      if (val != (int)item.Tag)
      {
        item.Text = val.ToString();
        item.Tag = val;
        return true;
      }
      return false;
    }
  }

  /// <summary>
  /// A listview item which contains a rate.
  /// </summary>
  internal class RateListViewItem : StatsCounterListViewItem
  {
    public RateListViewItem(IStatsCounter ctr, int filter_pid) :
      base(ctr.name)
    {
      StatsCounterRate rate = ctr as StatsCounterRate;
      Name = rate.name;
      SubItems.Add(NewSubItem());
      SubItems.Add(NewSubItem());
      SubItems.Add(NewSubItem());
      Update(ctr, filter_pid);
    }

    public override void Update(IStatsCounter counter, int filter_pid)
    {
      Debug.Assert(counter is StatsCounterRate);

      StatsCounterRate new_rate = counter as StatsCounterRate;
      int new_count = new_rate.GetCount(filter_pid);
      int new_time = new_rate.GetTime(filter_pid);
      int old_avg = Tag != null ? (int)Tag : 0;
      int new_avg = new_count > 0 ? (new_time / new_count) : 0;
      int delta = new_avg - old_avg;

      SetSubItem(SubItems[column_count_index], new_count);
      SetSubItem(SubItems[column_time_index], new_time);
      if (SetSubItem(SubItems[column_avg_index], new_avg)) 
        ColorItem(delta);
      Tag = new_avg;
    }

    private const int column_count_index = 1;
    private const int column_time_index = 2;
    private const int column_avg_index = 3;
  }

  /// <summary>
  /// A listview item which contains a counter.
  /// </summary>
  internal class CounterListViewItem : StatsCounterListViewItem
  {
    public CounterListViewItem(IStatsCounter ctr, int filter_pid) :
      base(ctr.name)
    {
      Name = ctr.name;
      SubItems.Add(NewSubItem());
      SubItems.Add(NewSubItem());
      Update(ctr, filter_pid);
    }

    public override void Update(IStatsCounter counter, int filter_pid) {
      Debug.Assert(counter is StatsCounter || counter is StatsTimer);

      int new_value = 0;
      if (counter is StatsCounter)
        new_value = ((StatsCounter)counter).GetValue(filter_pid);
      else if (counter is StatsTimer)
        new_value = ((StatsTimer)counter).GetValue(filter_pid);

      int old_value = Tag != null ? (int)Tag : 0;
      int delta = new_value - old_value;
      SetSubItem(SubItems[column_value_index], new_value);
      if (SetSubItem(SubItems[column_delta_index], delta))
        ColorItem(delta);
      Tag = new_value;
    }

    private const int column_value_index = 1;
    private const int column_delta_index = 2;
  }
}
