import os
import re
import unittest

from tempfile import NamedTemporaryFile

import tecplot as tp
from tecplot import tecutil, macro

from test import skip_if_connected, skip_if_sdk_version_before

class TestRecording(unittest.TestCase):
    @skip_if_connected
    def setUp(self):
        tp.new_layout()

    def check_mcr_file_header(self, file_header):
        first_line = file_header.split('\n')[0]
        self.assertIsNotNone(re.match(r'^#!MC\s\d\d\d\d\s*', first_line))

    def record_file(self, suffix, commands_to_run=None):
        file = NamedTemporaryFile(suffix=suffix, delete=False)
        file.close()  # Just need the name
        self.assertFalse(tecutil._tecutil_connector.tecutil_handle.tecUtilMacroIsRecordingActive())
        result = tecutil._tecutil_connector.macro_record_start(file.name)
        self.assertTrue(result)
        self.assertTrue(tecutil._tecutil_connector.tecutil_handle.tecUtilMacroIsRecordingActive())

        if commands_to_run is not None:
            for cmd in commands_to_run:
                macro.execute_command(cmd)

        tecutil._tecutil_connector.macro_record_end()
        self.assertFalse(tecutil._tecutil_connector.tecutil_handle.tecUtilMacroIsRecordingActive())
        self.assertTrue(os.path.exists(file.name))
        try:
            with open(file.name, 'r') as f:
                file_contents = f.read()
        finally:
            try:
                os.remove(file.name)
            except OSError as e:
                self.fail(msg='Could not delete temporary file:'.format(e))
        return file_contents

    def test_play_macro(self):
        tecplot_macro_file = NamedTemporaryFile(suffix='.mcr', delete=False)
        tecplot_macro_file.close()

        # No need to actually record any macro commands since we're
        # going to be checking for the filename.
        tecutil._tecutil_connector.macro_record_start(tecplot_macro_file.name)
        tecutil._tecutil_connector.macro_record_end()

        pytecplot_macro_file = NamedTemporaryFile(suffix='.py', delete=False)
        pytecplot_macro_file.close()

        tecutil._tecutil_connector.macro_record_start(pytecplot_macro_file.name)
        # The closest way to simulate the user selecting
        # Macro/Play Macro is to record an macro.execute_file() command,
        # which will end up in Action_RunFile(), which will record
        # macro.execute_file()
        tp.macro.execute_file(tecplot_macro_file.name)
        tecutil._tecutil_connector.macro_record_end()

        try:
            with open(pytecplot_macro_file.name, 'r') as f:
                file_contents = f.read()
                final_name = tecplot_macro_file.name.replace('\\', '\\\\')
                self.assertIn("macro.execute_file('{}')".format(final_name),
                              file_contents)
        finally:
            try:
                os.remove(tecplot_macro_file.name)
                os.remove(pytecplot_macro_file.name)
            except OSError as e:
                self.fail(msg='Could not delete temporary file:'.format(e))

    def test_that_a_real_pytecplot_file_is_recorded(self):
        with tp.tecutil.temporary_closed_file(suffix='.py') as ftmp:
            with tp.macro.record(ftmp):
                pass
            with open(ftmp, 'rt') as fin:
                file_contents = fin.read()
        self.assertIn('import tecplot', file_contents)

    def test_that_mcr_recording_without_raw_data_is_not_broken(self):
        with tp.macro.record(header='#!MC 1410\n') as buf:
            tp.macro.execute_command('''\
                $!CREATERECTANGULARZONE
                      IMAX = 10
                      JMAX = 10
                      KMAX = 10
                      X1 = 0
                      Y1 = 0
                      Z1 = 0
                      X2 = 1
                      Y2 = 1
                      Z2 = 1
                      XVAR = 1
                      YVAR = 2
                      ZVAR = 3''')
        file_contents = buf.getvalue()
        self.check_mcr_file_header(file_contents)
        self.assertIn('$!CREATERECTANGULARZONE', file_contents.upper())

    def test_that_mcr_recording_with_raw_data_is_not_broken(self):
        expected_contents ='''
$!ATTACHGEOM
  ANCHORPOS
    {
    X = 0.2787855444785277
    Y = 0.8375070552147239
    }
  RAWDATA
1
6
0 0
0.0122711658478 -0.561405837536
0.26843175292 -0.475507676601
0.427956908941 -0.0828303694725
0.233152151108 -0.0306779146194
0.665710747242 -0.549134671688'''
        with tp.macro.record(header='#!MC 1410\n') as buf:
            tp.macro.execute_command(expected_contents)
        file_contents = buf.getvalue()
        self.check_mcr_file_header(file_contents)
        self.assertIn(expected_contents, re.sub(r'\s*\n', r'\n', file_contents.upper()))


if __name__ == '__main__':
    import test
    test.main()
