from discord.ext import commands
from .utils import checks
import aiohttp
import json

class CodeBlock:
    def __init__(self, argument):
        block, code = argument.split('\n', 1)
        if not block.startswith('```') and not code.endswith('```'):
            raise commands.BadArgument('Could not find a code block.')

        language = block[3:]
        self.command = self.get_command_from_language(language)
        self.source = code.rstrip('`')

    def get_command_from_language(self, language):
        commands = {
            'cpp': 'g++ -std=c++14 -O2 -Wall -Wextra -pedantic -pthread main.cpp && ./a.out',
            'c': 'mv main.cpp main.c && gcc -std=c11 -O2 -Wall -Wextra -pedantic main.c && ./a.out',
            'py': 'python main.cpp', # coliru has no python3
            'python': 'python main.cpp',
            'haskell': 'runhaskell main.cpp'
        }

        try:
            return commands[language.lower()]
        except KeyError as e:
            raise commands.BadArgument('Unknown language to compile for: {}'.format(e)) from e

class Lounge:
    """Commands for Lounge<C++> only.

    Don't abuse these.
    """

    def __init__(self, bot):
        self.bot = bot

    # allow it in Lounge<C++> and Discord API
    @commands.command(pass_context=True)
    @checks.is_in_servers('81384788765712384', '145079846832308224')
    async def coliru(self, ctx, *, code : CodeBlock):
        """Compiles code via Coliru.

        You have to pass in a codeblock with the language syntax
        either set to one of these:

        - cpp
        - python
        - py
        - haskell

        Anything else isn't supported. The C++ compiler uses g++ -std=c++14.

        Please don't spam this for Stacked's sake.
        """
        payload = {
            'cmd': code.command,
            'src': code.source
        }

        data = json.dumps(payload)

        async with aiohttp.post('http://coliru.stacked-crooked.com/compile', data=data) as resp:
            if resp.status != 200:
                await self.bot.say('Coliru did not respond in time.')
                return
            output = await resp.text()

            if len(output) < 1992:
                fmt = '```\n{}\n```'.format(output)
                await self.bot.say(fmt)
                return

            # output is too big so post it in gist
            gist = {
                'description': 'The response for {0.author}\'s compilation.'.format(ctx.message),
                'public': True,
                'files': {
                    'output': {
                        'content': output
                    },
                    'original': {
                        'content': code.source
                    }
                }
            }

            async with aiohttp.post('https://api.github.com/gists', data=json.dumps(gist)) as gh:
                if gh.status != 201:
                    await self.bot.say('Could not create gist.')
                else:
                    js = await gh.json()
                    await self.bot.say('Output too big. The content is in: {0[html_url]}'.format(js))


    @coliru.error
    async def coliru_error(self, error, ctx):
        if isinstance(error, commands.BadArgument):
            await self.bot.say(error)

def setup(bot):
    bot.add_cog(Lounge(bot))

@@ -2355,419 +2355,8 @@
 ist%0A
-            gist = %7B%0A                'description': 'The response for %7B0.author%7D%5C's compilation.'.format(ctx.message),%0A                'public': True,%0A                'files': %7B%0A                    'output': %7B%0A                        'content': output%0A                    %7D,%0A                    'original': %7B%0A                        'content': code.source%0A                    %7D%0A                %7D%0A            %7D%0A%0A
     
@@ -2396,63 +2396,64 @@
 http
-s
 ://
-api.github.com/gists', data=json.dumps(gist)
+coliru.stacked-crooked.com/share', data=data
 ) as 
-gh
+resp
 :%0A  
@@ -2469,18 +2469,20 @@
      if 
-gh
+resp
 .status 
@@ -2486,17 +2486,17 @@
 us != 20
-1
+0
 :%0A      
@@ -2550,13 +2550,26 @@
 ate 
-gist.
+coliru shared link
 ')%0A 
@@ -2613,26 +2613,35 @@
     
-js = await gh.json
+shared_id = await resp.text
 ()%0A 
@@ -2699,54 +2699,71 @@
 ig. 
-The content is 
+Coliru l
 in
+k
 : 
-%7B0%5Bhtml_url%5D%7D'.format(js))%0A
+http://coliru.stacked-crooked.com/a/' + shared_id)
 %0A%0A  

Use coliru share link instead of gist in case of too big content.