import unittest
import stk
import os, sys, stat, time
 
def usage():
    """Show the usage with example for this module."""
                                                              
    print("""\nUsage:                                      
           % python unittest_stkbuild.py [opts] [-v]                 
            opt:   
              -t##:  run specific unit test, may occur multiple times
                -u:  this message                            
                -v:  debug option\n""")                       


class TestStkBuild(unittest.TestCase):
  """Test stack module build() functionality """

  toolname = "stk.build"

  def setUp(self):
    """ Set parameters prior to each test"""


  def test01(self):
    """ input is None  """

    try:
      # input NoneType name
      result = stk.build( None )

    except Exception as ex: # catch the error from build() function
        if str(ex).find("Could not parse arguments.") == -1:
          print( ex )
          raise Exception("Error: expected Exception not thrown")
        pass
    else:
      raise Exception("Error: No exception thrown for bad input.")

  def test02(self):
    """ input is empty string  """

    files = ""

    try:
      # input NoneType name
      result = stk.build( files )

    except Exception as ex: # catch the error from build() function
        if str(ex).find("Empty stack string.") == -1:
          print( ex )
          raise Exception("Error: expected Exception not thrown")
        pass
    else:
      raise Exception("Error: No exception thrown for bad input.")


  def test03(self):
    """ input is empty string with whitespace """

    files = "   "

    try:
      # input NoneType name
      result = stk.build( files )

    except ValueError as ve: # catch the error from build() function
        if str(ve).find("Stack has only 1 element and it is blank") == -1:
          print( ve )
          raise Exception("Error: expected ValueError exception not thrown")
        pass
    except Exception as ex:
        print(ex.__class__.__name__ + ": " + str(ex))
        raise Exception("Error: unexpected exception thrown")
    else:
      raise Exception("Error: No exception thrown for bad input.")


  def test04(self):
    """ input is file-system string  """

    files = "/data/bugs/a.fits,/proj/sciops/b.fits,/proj/xena/c.txt"
    expected = ["/data/bugs/a.fits", "/proj/sciops/b.fits", "/proj/xena/c.txt"]

    try:
      # input string
      result = stk.build( files )

    except Exception as ex:
        print(ex.__class__.__name__ + ": " + str(ex))
        raise Exception("Error: unexpected exception thrown")

    assert result is not None
    self.assertEqual( result[0], expected[0] )
    self.assertEqual( result[1], expected[1] )
    self.assertEqual( result[2], expected[2] )

  def test05(self):
    """ input is unicode string  """

    files = u"/data/bugs/a.fits,/proj/sciops/b.fits,/proj/xena/c.txt"
    expected = ["/data/bugs/a.fits", "/proj/sciops/b.fits", "/proj/xena/c.txt"]

    try:
      # input string
      result = stk.build( files )

    except Exception as ex:
        print(ex.__class__.__name__ + ": " + str(ex))
        raise Exception("Error: unexpected exception thrown")

    assert result is not None
    self.assertEqual( result[0], expected[0] )
    self.assertEqual( result[1], expected[1] )
    self.assertEqual( result[2], expected[2] )

  def test06(self):
    """ input is bytes string  """

    files = b"/data/bugs/a.fits,/proj/sciops/b.fits,/proj/xena/c.txt"
    expected = ["/data/bugs/a.fits", "/proj/sciops/b.fits", "/proj/xena/c.txt"]

    try:
      # input string
      result = stk.build( files )

    except Exception as ex:
        print(ex.__class__.__name__ + ": " + str(ex))
        raise Exception("Error: unexpected exception thrown")

    assert result is not None
    self.assertEqual( result[0], expected[0] )
    self.assertEqual( result[1], expected[1] )
    self.assertEqual( result[2], expected[2] )

  def test07(self):
    """ input is non-string  """

    files = 7  #non-string type

    try:
      result = stk.build( files )

    except Exception as ex: # catch the error from build() function
        if str(ex).find("Could not parse arguments.") == -1:
          print( ex )
          raise Exception("Error: expected Exception not thrown")
        pass
    else:
      raise Exception("Error: No exception thrown for bad input.")

  def test08(self):
    """ input is pattern matching path string """

    files = "/data/regression_test/master/in/stk_build/realdir1/*.fits"
    expected = ["/data/regression_test/master/in/stk_build/realdir1/file.fits", "/data/regression_test/master/in/stk_build/realdir1/file2.fits"]

    try:
      # input string
      result = stk.build( files )

    except Exception as ex:
      print(ex.__class__.__name__ + ": " + str(ex))
      raise Exception("Error: unexpected exception thrown")

    assert result is not None
    self.assertEqual( result[0], expected[0] )
    self.assertEqual( result[1], expected[1] )

  def test09(self):
    """ input is a directory that does not exist """

    files = "/data/regression_test/master/in/stk_build/realdir/"
    expected = ["/data/regression_test/master/in/stk_build/realdir/"]

    try:
      # input string
      result = stk.build( files )

    except Exception as ex:
      print(ex.__class__.__name__ + ": " + str(ex))
      raise Exception("Error: unexpected exception thrown")

    assert result is not None
    self.assertEqual( result[0], expected[0] )

if __name__ == '__main__':

  if "-u" in sys.argv[1:]:
    usage()
  elif len(sys.argv)==1 or (len(sys.argv)==2 and ("-v" in sys.argv or "-q" in sys.argv ) ):
    # run all tests
    unittest.main(defaultTest="TestStkBuild")
  else:

    suite = unittest.TestSuite()
    for arg in sys.argv[1:]:

      if arg.startswith("-t"):           # "-t01"
        tname = "test" + arg.strip("-t") # "test01"
        suite.addTest(TestCrateUtils(tname))

    unittest.TextTestRunner().run(suite)

