#!/usr/bin/python
# -*- coding: utf-8 -*-
#PYTHON_ARGCOMPLETE_OK

# <one line to give the library's name and an idea of what it does.>
# Copyright (C) 2014  <copyright holder> <email>
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

__doc__ = """
Dla zadanego katalogu, wyszukuje w nich wyników i podsumowuje je.
Podsumowuje wyjscie narzędzi:
  gsummarizer.py
  betweengsim.py

Czyta wyjscie betweengsim z podziału na katalogi z gsummarizer.
Jako wynik tworzy plik csv, w ktorym zapisuje informacje o konfiguracji
gsummarizera oraz sredniej wartosci dla miary per relcja.

Podaje się pojedynczy katalog (nie wyjście w postaci wszystkich katalogów)
Gdzie katalog to konkretna konfiguracja gsummarizera np.
  grafon_graphs__mintok-2_minnode-6_remzeronodes-True_maxnode-div-8

I taki katalog jest podawany do tego narzędzia
"""

import os, csv
import argparse
try:
    import argcomplete
except ImportError:
    argcomplete = None

def make_parser(desc = ''):
  aparser = argparse.ArgumentParser(description = desc)

  aparser.add_argument('-d', '--dir', dest='csv_res_dir', required=True,
                       help=('DIrectory with csv results from betweengsim'))
  aparser.add_argument('-o', '--out-file', dest='out_csv', required=True,
                       help=('Path to output file where results will are stored'))

  if argcomplete:
    argcomplete.autocomplete(aparser)
  return aparser

def find_csv_files(directory):
  """Return list of full path to csv files into given directory"""
  return [os.path.join(directory, f) 
          for f in os.listdir(directory) if f.endswith('.csv')]

def calculate_avg_sim_row(row, norm_factor):
  """
  calculates avg similarity in the row.
  Returns pair of {relation name, avg similarity}

  If norm_factor is given, then all values are divided by them.
  """
  vfloat = [(float(f)/(norm_factor if norm_factor else 1)) for f in row[1:]]
  return (row[0], sum(vfloat)/len(vfloat))


def find_max_in_csv(csvfile):
  """Finds maximum value in csv file."""
  max_v = 0.0
  with open(csvfile, 'rb') as csvfile:
    spamreader = csv.reader(csvfile, delimiter='\t', quotechar='"')
    for row in spamreader:
      if row[0] == '-':
        continue
      for v in row[1:]:
        max_v = float(v) if float(v) > max_v else max_v
  return max_v

def calculate_avg_sim_file(raw_csvfile, use_normalization=True):
  max_value = find_max_in_csv(raw_csvfile) if use_normalization else None
  with open(raw_csvfile, 'rb') as csvfile:
    spamreader = csv.reader(csvfile, delimiter='\t', quotechar='"')
    first = True
    for row in spamreader:
      # skip first line (a header)
      if row[0] == '-':
        continue
      measure_graph = os.path.basename(raw_csvfile).replace('.csv', '')
      relname, avg_sim = calculate_avg_sim_row(row, max_value)
      yield measure_graph, relname, avg_sim

def main(argv=None):
  p = make_parser(__doc__)
  args = p.parse_args(argv)

  with open(args.out_csv, 'wt') as outfile:
    with open('{}-detailed.csv'.format(args.out_csv), 'wt') as s_outfile:
      for csvfile in find_csv_files(args.csv_res_dir):
        resdict=dict()
        for measure_graph, relname, avg_sim in calculate_avg_sim_file(csvfile):
          s_outfile.write("{}\t{}\t{}\n".format(measure_graph, relname, avg_sim))
          if not resdict.has_key(measure_graph):
            resdict[measure_graph] = []
          resdict[measure_graph].append(avg_sim)
        for measure_graph, values in resdict.iteritems():
          outfile.write("{}\t{}\n".format(measure_graph, sum(values)/len(values)))

if __name__ == '__main__':
  main()