from telegram.ext import CommandHandler, run_async
from bot.gDrive import GoogleDriveHelper
from bot.fs_utils import get_readable_file_size
from bot import LOGGER, dispatcher, updater, bot
from bot.config import BOT_TOKEN, OWNER_ID, GDRIVE_FOLDER_ID
from bot.decorators import is_authorised, is_owner
from telegram.error import TimedOut, BadRequest
from bot.clone_status import CloneStatus
from bot.msg_utils import deleteMessage, sendMessage
import time

REPO_LINK = "https://t.me/KOT_BOTS"
# Soon to be used for direct updates from within the bot.

@run_async
def start(update, context):
    sendMessage("Hello! Please send me a Google Drive Shareable Link to Clone to your Drive!" \
        "\nSend /help for checking all available commands.",
    context.bot, update, 'Markdown')
    # ;-;

@run_async
def helper(update, context):
    sendMessage("Here are the available commands of the bot\n\n" \
        "*Usage:* `/clone <link> [DESTINATION_ID]`\n*Example:* \n1. `/clone https://drive.google.com/drive/u/1/folders/0AO-ISIXXXXXXXXXXXX`\n2. `/clone 0AO-ISIXXXXXXXXXXXX`" \
            "\n*DESTIONATION_ID* is optional. It can be either link or ID to where you wish to store a particular clone." \
            "\n\nYou can also *ignore folders* from clone process by doing the following:\n" \
                "`/clone <FOLDER_ID> [DESTINATION] [id1,id2,id3]`\n In this example: id1, id2 and id3 would get ignored from cloning\nDo not use <> or [] in actual message." \
                    "*Make sure to not put any space between commas (,).*\n" \
                        f"Source of this bot: [GitHub]({REPO_LINK})", context.bot, update, 'Markdown')

# TODO Cancel Clones with /cancel command.
@run_async
@is_authorised
def cloneNode(update, context):
    args = update.message.text.split(" ")
    if len(args) > 1:
        link = args[1]
        try:
            ignoreList = args[-1].split(',')
        except IndexError:
            ignoreList = []

        DESTINATION_ID = GDRIVE_FOLDER_ID
        try:
            DESTINATION_ID = args[2]
            print(DESTINATION_ID)
        except IndexError:
            pass
            # Usage: /clone <FolderToClone> <Destination> <IDtoIgnoreFromClone>,<IDtoIgnoreFromClone>

        msg = sendMessage(f"<b>Cloning:</b> <code>{link}</code>", context.bot, update)
        status_class = CloneStatus()
        gd = GoogleDriveHelper(GFolder_ID=DESTINATION_ID)
        sendCloneStatus(update, context, status_class, msg, link)
        result = gd.clone(link, status_class, ignoreList=ignoreList)
        deleteMessage(context.bot, msg)
        status_class.set_status(True)
        sendMessage(result, context.bot, update)
    else:
        sendMessage("Please Provide a Google Drive Shared Link to Clone.", bot, update)


@run_async
def sendCloneStatus(update, context, status, msg, link):
    old_text = ''
    while not status.done():
        sleeper(3)
        try:
            text=f'🔗 *Cloning:* [{status.MainFolderName}]({status.MainFolderLink})\n━━━━━━━━━━━━━━\n🗃️ *Current File:* `{status.get_name()}`\n⬆️ *Transferred*: `{status.get_size()}`\n📁 *Destination:* [{status.DestinationFolderName}]({status.DestinationFolderLink})'
            if status.checkFileStatus():
                text += f"\n🕒 *Checking Existing Files:* `{str(status.checkFileStatus())}`"
            if not text == old_text:
                msg.edit_text(text=text, parse_mode="Markdown", timeout=200)
                old_text = text
        except Exception as e:
            LOGGER.error(e)
            if str(e) == "Message to edit not found":
                break
            sleeper(2)
            continue
    return

def sleeper(value, enabled=True):
    time.sleep(int(value))
    return

@run_async
@is_owner
def sendLogs(update, context):
    with open('log.txt', 'rb') as f:
        bot.send_document(document=f, filename=f.name,
                        reply_to_message_id=update.message.message_id,
                        chat_id=update.message.chat_id)

def main():
    LOGGER.info("Bot Started!")
    clone_handler = CommandHandler('clone', cloneNode)
    start_handler = CommandHandler('start', start)
    help_handler = CommandHandler('help', helper)
    log_handler = CommandHandler('logs', sendLogs)
    dispatcher.add_handler(log_handler)
    dispatcher.add_handler(start_handler)
    dispatcher.add_handler(clone_handler)
    dispatcher.add_handler(help_handler)
    updater.start_polling()

main()

[((17, 4, 19, 36), 'bot.msg_utils.sendMessage', 'sendMessage', ({(17, 16, 18, 59): '"""Hello! Please send me a Google Drive Shareable Link to Clone to your Drive!\nSend /help for checking all available commands."""', (19, 4, 19, 15): 'context.bot', (19, 17, 19, 23): 'update', (19, 25, 19, 35): '"""Markdown"""'}, {}), '(\n    """Hello! Please send me a Google Drive Shareable Link to Clone to your Drive!\nSend /help for checking all available commands."""\n    , context.bot, update, \'Markdown\')', False, 'from bot.msg_utils import deleteMessage, sendMessage\n'), ((24, 4, 30, 102), 'bot.msg_utils.sendMessage', 'sendMessage', ({(24, 16, 30, 68): 'f"""Here are the available commands of the bot\n\n*Usage:* `/clone <link> [DESTINATION_ID]`\n*Example:* \n1. `/clone https://drive.google.com/drive/u/1/folders/0AO-ISIXXXXXXXXXXXX`\n2. `/clone 0AO-ISIXXXXXXXXXXXX`\n*DESTIONATION_ID* is optional. It can be either link or ID to where you wish to store a particular clone.\n\nYou can also *ignore folders* from clone process by doing the following:\n`/clone <FOLDER_ID> [DESTINATION] [id1,id2,id3]`\n In this example: id1, id2 and id3 would get ignored from cloning\nDo not use <> or [] in actual message.*Make sure to not put any space between commas (,).*\nSource of this bot: [GitHub]({REPO_LINK})"""', (30, 70, 30, 81): 'context.bot', (30, 83, 30, 89): 'update', (30, 91, 30, 101): '"""Markdown"""'}, {}), '(\n    f"""Here are the available commands of the bot\n\n*Usage:* `/clone <link> [DESTINATION_ID]`\n*Example:* \n1. `/clone https://drive.google.com/drive/u/1/folders/0AO-ISIXXXXXXXXXXXX`\n2. `/clone 0AO-ISIXXXXXXXXXXXX`\n*DESTIONATION_ID* is optional. It can be either link or ID to where you wish to store a particular clone.\n\nYou can also *ignore folders* from clone process by doing the following:\n`/clone <FOLDER_ID> [DESTINATION] [id1,id2,id3]`\n In this example: id1, id2 and id3 would get ignored from cloning\nDo not use <> or [] in actual message.*Make sure to not put any space between commas (,).*\nSource of this bot: [GitHub]({REPO_LINK})"""\n    , context.bot, update, \'Markdown\')', False, 'from bot.msg_utils import deleteMessage, sendMessage\n'), ((97, 4, 97, 31), 'bot.LOGGER.info', 'LOGGER.info', ({(97, 16, 97, 30): '"""Bot Started!"""'}, {}), "('Bot Started!')", False, 'from bot import LOGGER, dispatcher, updater, bot\n'), ((98, 20, 98, 54), 'telegram.ext.CommandHandler', 'CommandHandler', ({(98, 35, 98, 42): '"""clone"""', (98, 44, 98, 53): 'cloneNode'}, {}), "('clone', cloneNode)", False, 'from telegram.ext import CommandHandler, run_async\n'), ((99, 20, 99, 50), 'telegram.ext.CommandHandler', 'CommandHandler', ({(99, 35, 99, 42): '"""start"""', (99, 44, 99, 49): 'start'}, {}), "('start', start)", False, 'from telegram.ext import CommandHandler, run_async\n'), ((100, 19, 100, 49), 'telegram.ext.CommandHandler', 'CommandHandler', ({(100, 34, 100, 40): '"""help"""', (100, 42, 100, 48): 'helper'}, {}), "('help', helper)", False, 'from telegram.ext import CommandHandler, run_async\n'), ((101, 18, 101, 50), 'telegram.ext.CommandHandler', 'CommandHandler', ({(101, 33, 101, 39): '"""logs"""', (101, 41, 101, 49): 'sendLogs'}, {}), "('logs', sendLogs)", False, 'from telegram.ext import CommandHandler, run_async\n'), ((102, 4, 102, 39), 'bot.dispatcher.add_handler', 'dispatcher.add_handler', ({(102, 27, 102, 38): 'log_handler'}, {}), '(log_handler)', False, 'from bot import LOGGER, dispatcher, updater, bot\n'), ((103, 4, 103, 41), 'bot.dispatcher.add_handler', 'dispatcher.add_handler', ({(103, 27, 103, 40): 'start_handler'}, {}), '(start_handler)', False, 'from bot import LOGGER, dispatcher, updater, bot\n'), ((104, 4, 104, 41), 'bot.dispatcher.add_handler', 'dispatcher.add_handler', ({(104, 27, 104, 40): 'clone_handler'}, {}), '(clone_handler)', False, 'from bot import LOGGER, dispatcher, updater, bot\n'), ((105, 4, 105, 40), 'bot.dispatcher.add_handler', 'dispatcher.add_handler', ({(105, 27, 105, 39): 'help_handler'}, {}), '(help_handler)', False, 'from bot import LOGGER, dispatcher, updater, bot\n'), ((106, 4, 106, 27), 'bot.updater.start_polling', 'updater.start_polling', ({}, {}), '()', False, 'from bot import LOGGER, dispatcher, updater, bot\n'), ((52, 14, 52, 86), 'bot.msg_utils.sendMessage', 'sendMessage', ({(52, 26, 52, 64): 'f"""<b>Cloning:</b> <code>{link}</code>"""', (52, 66, 52, 77): 'context.bot', (52, 79, 52, 85): 'update'}, {}), "(f'<b>Cloning:</b> <code>{link}</code>', context.bot, update)", False, 'from bot.msg_utils import deleteMessage, sendMessage\n'), ((53, 23, 53, 36), 'bot.clone_status.CloneStatus', 'CloneStatus', ({}, {}), '()', False, 'from bot.clone_status import CloneStatus\n'), ((54, 13, 54, 57), 'bot.gDrive.GoogleDriveHelper', 'GoogleDriveHelper', (), '', False, 'from bot.gDrive import GoogleDriveHelper\n'), ((57, 8, 57, 39), 'bot.msg_utils.deleteMessage', 'deleteMessage', ({(57, 22, 57, 33): 'context.bot', (57, 35, 57, 38): 'msg'}, {}), '(context.bot, msg)', False, 'from bot.msg_utils import deleteMessage, sendMessage\n'), ((59, 8, 59, 48), 'bot.msg_utils.sendMessage', 'sendMessage', ({(59, 20, 59, 26): 'result', (59, 28, 59, 39): 'context.bot', (59, 41, 59, 47): 'update'}, {}), '(result, context.bot, update)', False, 'from bot.msg_utils import deleteMessage, sendMessage\n'), ((61, 8, 61, 87), 'bot.msg_utils.sendMessage', 'sendMessage', ({(61, 20, 61, 73): '"""Please Provide a Google Drive Shared Link to Clone."""', (61, 75, 61, 78): 'bot', (61, 80, 61, 86): 'update'}, {}), "('Please Provide a Google Drive Shared Link to Clone.', bot, update)", False, 'from bot.msg_utils import deleteMessage, sendMessage\n'), ((92, 8, 94, 55), 'bot.bot.send_document', 'bot.send_document', (), '', False, 'from bot import LOGGER, dispatcher, updater, bot\n'), ((77, 12, 77, 27), 'bot.LOGGER.error', 'LOGGER.error', ({(77, 25, 77, 26): 'e'}, {}), '(e)', False, 'from bot import LOGGER, dispatcher, updater, bot\n')]