#!/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__ = '''
Oblicza podobieństwo między grafami (osobno from/to) z zadanego katalogu.
Służy do obliczenia podobieństwa między grafami utworzonymi dla danych 
z entailmentu. 
'''

import os, sys, networkx
try:
  import argcomplete
except ImportError:
  argcomplete = None

from grafon import grafon_base
from grafon.utils.grafonconfig import GrafonConfig

def make_parser(desc = ''):
  aparser = grafon_base.make_parser(desc)
  aparser.add_argument(
    '-d', '--graphs-dir', dest='graphs_dir', required=True, type=str,
    help=('Directory where the graphs are stored, and results will be stored'))
  if argcomplete:
    argcomplete.autocomplete(aparser)
  return aparser

def read_graphs(graphs_dir):
  """
  Reads graphs from given directory

  @return dictionary where the key is relation name and value is pair of
          networkx.MultiDiGraphs in order: {from, to}
  @rtype dict[str]->{networkx.MultiDiGraph, networkx.MultiDiGraph}
  """
  gdict = {}
  if not os.path.exists(graphs_dir):
    raise Exception("Given directory does not exists!")

  for gf in os.listdir(graphs_dir):
    if not gf.endswith(".pickle"):
      continue
    print >> sys.stderr, "Reading graph {}".format(gf) 
    g = networkx.read_gpickle("{}/{}".format(graphs_dir, gf))
    rname, ginfo = gf.split("_#_")
    if not gdict.has_key(rname):
      gdict[rname] = [None, None]
    gdict[rname][0 if ginfo.find("from_graph") > -1 else 1] = g

  return gdict

def calculate_measure(measures, gdict, graphs_dir):
  """
  @param measures List of measures to calculate
  @type measures: grafon.measures
  
  @param gdict Dictionary of graphs to calculate (returned from read_graphs)
  @type gdict: Dictionary of [str]=>{networkx.MultiDiGraph, networkx.MultiDiGraph}
  """
  for m in measures:
    res_f = open('{}/{}_from.csv'.format(graphs_dir, str(m)), 'wt')
    res_t = open('{}/{}_to__.csv'.format(graphs_dir, str(m)), 'wt')

    header = '-\t{}'.format('\t'.join(k for k in gdict.keys()))
    res_f.write('{}\n'.format(header))
    res_t.write('{}\n'.format(header))

    for rname1, (gf1, gt1) in gdict.iteritems():
      print >> sys.stderr, \
        '[{}] Calculating similarity for relation {}'.format(
        str(m), rname1)
      res_f.write('{}'.format(rname1))
      res_t.write('{}'.format(rname1))

      for rname2, (gf2, gt2) in gdict.iteritems():
        fsim = m.calculate(gf1, gf2)
        res_f.write('\t{}'.format(fsim))
        tsim = m.calculate(gt1, gt2)
        res_t.write('\t{}'.format(tsim))
      res_f.write('\n')
      res_t.write('\n')
    res_f.close()
    res_t.close()

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

  gdict = read_graphs(args.graphs_dir)
  calculate_measure(cfg.measures(), gdict, args.graphs_dir)

if __name__ == '__main__':
  print >> sys.stderr, '[SIMILARITY]'
  main()