#!/usr/bin/env python2.2
########################################
# The contents of this file are subject to the MLX PUBLIC LICENSE version
# 1.0 (the "License"); you may not use this file except in
# compliance with the License.
# 
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
# the License for the specific language governing rights and limitations
# under the License.
# 
# The Original Source Code is "compClust", released 2003 September 03.
# 
# The Original Source Code was developed by the California Institute of
# Technology (Caltech).  Portions created by Caltech are Copyright (C)
# 2002-2003 California Institute of Technology. All Rights Reserved.
########################################

import inspect
import os
import string
import sys
import tempfile
import unittest

from compClust.util import WrapperUtil
from compClust.mlx.wrapper import KMeans
from compClust.mlx.wrapper import Launcher

import compClust.mlx.wrapper

class HierarchicalTestCases(unittest.TestCase):

  def setUp(self):
    """Create temporary directory and file handles for test runs of mccv.
    """
    source = os.path.realpath(inspect.getsourcefile(HierTestCases))
    self.datadir = os.path.split(source)[0]
    self.executable=string.join([sys.executable,
                                 os.path.join(self.datadir,'..','KMeans.py')])
    
    self.original_dir    = os.getcwd()
    os.chdir(compClust.mlx.wrapper.__path__[0])
    self.temp_dir_name = WrapperUtil.create_temporary_directory("htst")

    self.orig_tempdir     = tempfile.tempdir
    tempfile.tempdir      = self.temp_dir_name
    self.param_filename   = tempfile.mktemp("parameter_file")
    self.param_stream     = open(self.param_filename, "w")
    self.result_filename  = tempfile.mktemp("result_file")

  def tearDown(self):
    """Clean up after ourselves.
    """
    tempfile.tempdir = self.orig_tempdir
    # FIXME: should this delete files that setUp did not create?
    
    try:
      os.remove(self.result_filename)
    except OSError, e:
      # result_filename may or may not exist so ignore deletion failures
      pass
    self.param_stream.close()
    os.remove(self.param_filename)
    os.rmdir(self.temp_dir_name)
    os.chdir(self.original_dir)
    
  def getParameters(self, k=5):
    return ["distance_metric = 'euclidean'",
            "init_means      = 'church'",
            "k               = %d" %(k),
            "num_iterations  = 100",
            "hierarchical    = 'on'",
            "prologues       = ['Terminator.clusterSize(10)']"
            ]

  def test_kmeans_small_tree_reasonable_k(self):
    """Test hier using a small tree search for a number of clusters
    that is noticably below the number of data points.

    """
    data_filename = os.path.join(self.datadir,
                                 "synth_t_05c0_p_0075_d_03_v_0d1.txt")
    result_filename = os.path.join(self.datadir, 'hier.small')

    parameters = self.getParameters()
    
    self.param_stream.write(string.join(parameters, "\n"))
    self.param_stream.close()

    argv=[self.executable, self.param_filename, data_filename, \
          self.result_filename] 
    result = Launcher.main(argv, KMeans())
    result = os.system("cmp -s %s "%(self.result_filename) + `self.result_filename`)
    
    self.failIf(result != 0, "small tree failed")

    
def suite(**kw):
  print "Hierarchical needs to be updated to the current API"
  return None
  suite = unittest.TestSuite()
  if os.environ.has_key("KMEANS_COMMAND"):
    suite.addTest(HierTestCases("test_kmeans_small_tree_reasonable_k"))
    #suite.addTest(MCCVTestCases("test_kmeans_medium_tree_reasonable_k"))
    #suite.addTest(MCCVTestCases("test_kmeans_large_tree_reasonable_k"))
  else:
    print "Hierarchical depends on KMEANS_COMMAND, hierarchical tests skipped"

  return suite

if __name__ == "__main__":
  unittest.main(defaultTest="suite")
