import os
import re
import tempfile

import shutil

from mpf.tests.MpfTestCase import MpfTestCase


class MpfDocTestCase(MpfTestCase):

    def __init__(self, config_string, methodName='test_config_parsing'):
        super().__init__(methodName)
        config_string = self.prepare_config(config_string)
        self.config_dir = tempfile.mkdtemp()
        os.mkdir(os.path.join(self.config_dir, "config"))
        with open(os.path.join(self.config_dir, "config", "config.yaml"), "w") as f:
            f.write(config_string)
        os.mkdir(os.path.join(self.config_dir, "modes"))
        os.mkdir(os.path.join(self.config_dir, "modes", "mode1"))
        self.addCleanup(self._delete_tmp_dir, self.config_dir)

    def getOptions(self):
        options = super().getOptions()
        # no cache since we are in a tmp folder anyway
        options['no_load_cache'] = True,
        options['create_config_cache'] = False
        return options

    def prepare_config(self, config_string):
        # add config_version if missing in example
        if not config_string.startswith("#config_version=5"):
            config_string = "#config_version=5\n" + config_string

        # inline invisible comments from documentation
        config_string = re.sub(r'#!\s+([^\n]+)', '\\1', config_string, re.MULTILINE)

        return config_string

    def getConfigFile(self):
        return "config.yaml"

    def getMachinePath(self):
        return self.config_dir

    def _delete_tmp_dir(self, config_dir):
        shutil.rmtree(config_dir)

    def test_config_parsing(self):
        pass

@@ -247,29 +247,44 @@
         
-config_string
+machine_config, mode_configs
  = self.
@@ -357,16 +357,49 @@
 kdtemp()
+%0A%0A        # create machine config
 %0A       
@@ -554,31 +554,177 @@
 f.write(
-config_string)%0A
+machine_config)%0A%0A        # create modes%0A        os.mkdir(os.path.join(self.config_dir, %22modes%22))%0A        for mode_name, mode_config in mode_configs.items():%0A    
         
@@ -761,35 +761,50 @@
 fig_dir, %22modes%22
-))%0A
+, mode_name))%0A    
         os.mkdir
@@ -847,17 +847,211 @@
 s%22, 
-%22mode1%22))
+mode_name, %22config%22))%0A            with open(os.path.join(self.config_dir, %22modes%22, mode_name, %22config%22, mode_name + %22.yaml%22), %22w%22) as f:%0A                f.write(mode_config)%0A%0A        # cleanup at the end
 %0A   
@@ -1402,76 +1402,370 @@
   # 
-add config_version if missing in example%0A        if not config_strin
+inline invisible comments from documentation%0A        config_string = re.sub(r'%5E#! (%5B%5E%5Cn%5D+)', '%5C%5C1', config_string, flags=re.MULTILINE)%0A%0A        # first find sections%0A        configs = re.split(r'%5E##! config: (%5Cw+)%5Cn', config_string, flags=re.MULTILINE)%0A        machine_config = configs.pop(0)%0A%0A        # add config_version if missing%0A        if not machine_confi
 g.st
@@ -1803,36 +1803,37 @@
             
-config_strin
+machine_confi
 g = %22#config
@@ -1852,192 +1852,535 @@
 %22 + 
-config_string%0A%0A        # inline invisible comments from documentation%0A        config_string = re.sub(r'#!%5Cs+(%5B%5E%5Cn%5D+)', '%5C%5C1', config_string, re.MULTILINE)%0A%0A        return config_string
+machine_config%0A%0A        modes = %7B%7D%0A        while configs:%0A            mode_name = configs.pop(0)%0A            mode_config = configs.pop(0)%0A            if not mode_config.startswith(%22#config_version=5%22):%0A                mode_config = %22#config_version=5%5Cn%22 + mode_config%0A            modes%5Bmode_name%5D = mode_config%0A%0A        # load all modes%0A        if modes:%0A            machine_config += %22%5Cnmodes:%5Cn%22%0A            for mode in modes.keys():%0A                machine_config += %22 - %22 + mode + %22%5Cn%22%0A%0A        return machine_config, modes
 %0A%0A  

extend MpfDocTestCase