#! /usr/bin/env /usr/local/bin/python

import os.path
import unittest
#import pdb

import pyx12.error_handler
#from error_handler import ErrorErrhNull
from pyx12.errors import *
from pyx12.map_walker import walk_tree
import pyx12.map_if
from pyx12.params import params


class Explicit_Loops(unittest.TestCase):
    """
    FAIL - no end tag for explicit loop
    """
    def setUp(self):
        self.walker = walk_tree()
        param = params()
        param.set_param('map_path', os.path.expanduser('~/src/pyx12/map/'))
        param.set_param('pickle_path', os.path.expanduser('~/src/pyx12/map/'))
        self.map = pyx12.map_if.load_map_file('837.4010.X098.A1.xml', param)
        self.errh = pyx12.error_handler.errh_null()

    def test_ISA_to_GS(self):
        node = self.map.getnodebypath('/ISA')
        seg = ['GS', 'HC']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)

    def test_GS_to_ST(self):
        node = self.map.getnodebypath('/GS')
        seg = ['ST', '837']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)

    def test_SE_to_ST(self):
        node = self.map.getnodebypath('/SE')
        seg = ['ST', '837']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)

    def test_SE_to_GE(self):
        node = self.map.getnodebypath('/SE')
        seg = ['GE', '1']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)

    def test_GE_to_GS(self):
        node = self.map.getnodebypath('/GE')
        seg = ['GS', '1']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)

    def test_GE_to_IEA(self):
        node = self.map.getnodebypath('/GE')
        self.assertEqual('GE', node.id)
        seg = ['IEA', '1']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)

    def test_IEA_to_ISA(self):
        node = self.map.getnodebypath('/IEA')
        self.assertEqual('IEA', node.id)
        seg = ['ISA', '1']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)

    def test_ST_to_BHT_fail(self):
        node = self.map.getnodebypath('/ST')
        seg = ['ZZZ', '0019']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(node, None)

    def tearDown(self):
        del self.errh
        del self.map
        del self.walker
        

class Implicit_Loops(unittest.TestCase):
    """
    FAIL - Mandatory segment skipped
    FAIL - Mandatory loop skipped

    TA1 segment

    child loop
    next sibling loop
    end loop - goto parent loop
    
    start at loop node
    start at segment node
    start at element/composite node?

    MATCH loop by first segment
    MATCH HL segment

    FAIL - loop repeat exceeds max count
    OK - loop repeat does not exceed max count
    

    """

    def setUp(self):
        self.walker = walk_tree()
        param = params()
        param.set_param('map_path', os.path.expanduser('~/src/pyx12/map/'))
        param.set_param('pickle_path', os.path.expanduser('~/src/pyx12/map/'))
        self.map = pyx12.map_if.load_map_file('837.4010.X098.A1.xml', param)
        self.errh = pyx12.error_handler.errh_null()

    def test_ST_to_BHT(self):
        node = self.map.getnodebypath('/ST')
        seg = ['BHT', '0019']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)

    def test_repeat_loop_with_one_segment(self):
        param = params()
        param.set_param('map_path', os.path.expanduser('~/src/pyx12/map/'))
        param.set_param('pickle_path', os.path.expanduser('~/src/pyx12/map/'))
        map = pyx12.map_if.load_map_file('841.4010.XXXC.xml', param)
        node = map.getnodebypath('/1000/2000/2100/SPI')
        seg = ['SPI', '00']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)

    def tearDown(self):
        del self.errh
        del self.map
        del self.walker
        
class SegmentWalk(unittest.TestCase):
    """
    FAIL - segment repeat exceeds max count
    OK - segment repeat does not exceed max count
    FAIL - found not used segment
    FAIL - segment was not found
    """

    def setUp(self):
        self.walker = walk_tree()
        param = params()
        param.set_param('map_path', os.path.expanduser('~/src/pyx12/map/'))
        param.set_param('pickle_path', os.path.expanduser('~/src/pyx12/map/'))
        self.map = pyx12.map_if.load_map_file('837.4010.X098.A1.xml', param)
        self.errh = pyx12.error_handler.errh_null()

    def test_match_regular_segment(self):
        node = self.map.getnodebypath('/2000A/2010AB/NM1')
        seg = ['N4', 'Billings', 'MT', '56123']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)
    
    def test_match_ID_segment1(self):
        node = self.map.getnodebypath('/2000A/2000B/2300/CLM')
        seg = ['DTP', '454', 'D8', '20040101']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)
    
    def test_match_ID_segment2(self):
        node = self.map.getnodebypath('/2000A/2000B/2300/CLM')
        seg = ['DTP', '304', 'D8', '20040201']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(seg[0], node.id)
    
#    def test_fail_ID_segment(self):
#        node = self.map.getnodebypath('/2000A/2000B/2300/CLM')
#        seg = ['DTP', '999', 'D8', '20040201']
#        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
#        self.assertNotEqual(seg[0], node.id)
    
    def tearDown(self):
        del self.errh
        del self.map
        del self.walker
        
class Segment_ID_Checks(unittest.TestCase):

    def setUp(self):
        self.walker = walk_tree()
        param = params()
        param.set_param('map_path', os.path.expanduser('~/src/pyx12/map/'))
        param.set_param('pickle_path', os.path.expanduser('~/src/pyx12/map/'))
        self.map = pyx12.map_if.load_map_file('837.4010.X098.A1.xml', param)
        self.errh = pyx12.error_handler.errh_null()
        self.node = self.map.getnodebypath('/ST')

    def test_segment_id_short(self):
        node = self.node
        seg = ['Z', '0019']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(node, None)
        self.assertEqual(self.errh.err_cde, '1', self.errh.err_str)

    def test_segment_id_long(self):
        node = self.node
        seg = ['ZZZZ', '0019']
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(node, None)
        self.assertEqual(self.errh.err_cde, '1', self.errh.err_str)

    def test_segment_empty(self):
        node = self.node
        seg = []
        node = self.walker.walk(node, seg, self.errh, 5, 4, None)
        self.assertEqual(node, None)
        self.assertEqual(self.errh.err_cde, '1', self.errh.err_str)


def suite():
    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(Explicit_Loops))
    suite.addTest(unittest.makeSuite(Implicit_Loops))
    suite.addTest(unittest.makeSuite(SegmentWalk))
    suite.addTest(unittest.makeSuite(Segment_ID_Checks))
    return suite

#if __name__ == "__main__":
#    unittest.main()
unittest.TextTestRunner(verbosity=2).run(suite())

