# ------------------
# Only for running this script here
import asyncio
import logging
import sys
from os.path import dirname

sys.path.insert(1, f"{dirname(__file__)}/../../..")
logging.basicConfig(level=logging.DEBUG)
# ------------------

# ---------------------
# Flask App
# ---------------------

# pip3 install flask
from flask import Flask, make_response

app = Flask(__name__)
logger = logging.getLogger(__name__)

import os

from slack import WebClient
from slack.errors import SlackApiError

singleton_client = WebClient(token=os.environ["SLACK_BOT_TOKEN"], run_async=False)

singleton_loop = asyncio.new_event_loop()
singleton_async_client = WebClient(
    token=os.environ["SLACK_BOT_TOKEN"],
    run_async=True,
    loop=singleton_loop
)


# Fixed in 2.6.0: This doesn't work
@app.route("/sync/singleton", methods=["GET"])
def singleton():
    try:
        # blocking here!!!
        # as described at https://github.com/slackapi/python-slackclient/issues/497
        # until this completion, other simultaneous requests get "RuntimeError: This event loop is already running"
        response = singleton_client.chat_postMessage(
            channel="#random",
            text="You used the singleton WebClient for posting this message!"
        )
        return str(response)
    except SlackApiError as e:
        return make_response(str(e), 400)


@app.route("/sync/per-request", methods=["GET"])
def per_request():
    try:
        client = WebClient(
            token=os.environ["SLACK_BOT_TOKEN"],
            run_async=False
        )
        response = client.chat_postMessage(
            channel="#random",
            text="You used a new WebClient for posting this message!"
        )
        return str(response)
    except SlackApiError as e:
        return make_response(str(e), 400)


# This doesn't work
@app.route("/async/singleton", methods=["GET"])
def singleton_async():
    try:
        future = singleton_async_client.chat_postMessage(
            channel="#random",
            text="You used the singleton WebClient for posting this message!"
        )
        # blocking here!!!
        # as described at https://github.com/slackapi/python-slackclient/issues/497
        # until this completion, other simultaneous requests get "RuntimeError: This event loop is already running"
        response = singleton_loop.run_until_complete(future)
        return str(response)
    except SlackApiError as e:
        return make_response(str(e), 400)


@app.route("/async/per-request", methods=["GET"])
def per_request_async():
    try:
        # This is not optimal and the host should have a large number of FD (File Descriptor)
        loop_for_this_request = asyncio.new_event_loop()

        async_client = WebClient(
            token=os.environ["SLACK_BOT_TOKEN"],
            run_async=True,
            loop=loop_for_this_request
        )
        future = async_client.chat_postMessage(
            channel="#random",
            text="You used the singleton WebClient for posting this message!"
        )
        response = loop_for_this_request.run_until_complete(future)
        return str(response)
    except SlackApiError as e:
        return make_response(str(e), 400)


if __name__ == "__main__":
    # export FLASK_ENV=development
    # python3 integration_tests/samples/issues/issue_497.py
    app.run(debug=True, host="localhost", port=3000)