#! /usr/bin/env python3.6
# coding: utf-8
from logger import log

import random
import time
import itertools
import contextlib
import dropbox

import config
import database_manager


class DropPics:
    def __init__(self, db):
        self.db = db
        cursor = self.db.cursor()
        self.years = self.get_years(cursor)
        self.topics = self.get_topics(cursor)
        self.possible_args = self.topics | self.years | set(config.slack_nicks_to_garg_ids.keys())

    def get_years(self, cursor):
        sql_command = "SELECT DISTINCT YEAR(taken) FROM dbx_pictures ORDER BY YEAR(taken)"
        cursor.execute(sql_command)
        return set(str(year[0]) for year in cursor.fetchall())

    def get_topics(self, cursor):
        sql_command = "SELECT topic FROM dbx_pictures"
        cursor.execute(sql_command)
        return set(topic[0] for topic in cursor.fetchall())

    def connect_dbx(self):
        self.dbx = dropbox.Dropbox(config.dropbox_token)
        self.dbx.users_get_current_account()
        log.info("Connected to dbx")

    def get_sql_for_args(self, args):
        sql_filter = []
        data = {}

        with contextlib.suppress(StopIteration):
            topic = next(arg for arg in args if arg in self.topics)
            sql_filter.append("p.topic = %(topic)s")
            data["topic"] = topic

        with contextlib.suppress(StopIteration):
            year = next(arg for arg in args if arg in self.years)
            sql_filter.append("YEAR(p.taken) = %(year)s")
            data["year"] = year

        try:
            garg_id = next(
                garg_id
                for user, garg_id in config.slack_nicks_to_garg_ids.items()
                if user in args
            )
            sql_filter.append("f.garg_id = %(garg_id)s")
            data["garg_id"] = garg_id
            join = 'LEFT JOIN dbx_pictures_faces as f ON p.pic_id = f.pic_id'
        except StopIteration:
            join = ""

        if sql_filter:
            sql_filter = "WHERE " + " AND ".join(sql_filter)

        sql_command = (
            'SELECT p.path, p.taken FROM dbx_pictures as p '
            f'{join} {sql_filter} ORDER BY RAND() LIMIT 1'
        )
        return sql_command, data

    def get_timestamp(self, date_obj):
        return int(time.mktime(date_obj.timetuple()))

    def get_url(self, path):
        response = self.dbx.sharing_create_shared_link(path)
        url = response.url.replace("?dl=0", "?raw=1")
        return url

    def get_pic(self, *args):
        error_text = ""
        cursor = self.db.cursor()

        if args:
            args = set(args)
            invalid_args = args - self.possible_args
            valid_args = args - invalid_args
            if invalid_args:
                invalid_args_fmt = ", ".join(f"`{arg}`" for arg in invalid_args)
                years_fmt = ", ".join(f"`{year}`" for year in sorted(self.years))
                topics_fmt = ", ".join(f"`{topic}`" for topic in self.topics)
                slack_nicks_fmt = ", ".join(f"`{user}`" for user in
                                            config.slack_nicks_to_garg_ids.keys())
                error_text = (
                    f"Im so stoopid! Skjønte ikke {invalid_args_fmt}. =( Jeg skjønner bare "
                    f"\n*år*: {years_fmt};\n"
                    f"*emner*: {topics_fmt};\n"
                    f"samt *garlings* - husk å bruke slack nick: {slack_nicks_fmt}\n"
                )

            if valid_args:
                sql_command, data = self.get_sql_for_args(valid_args)

                valid_args_fmt = ", ".join(f"`{arg}`" for arg in valid_args)

                cursor.execute(sql_command, data)
                data = cursor.fetchone()
                if data is not None:
                    path, date_obj = data
                    url = self.get_url(path)
                    timestamp = self.get_timestamp(date_obj)
                    if invalid_args:
                        error_text += f"Her er et bilde med {valid_args_fmt}:"
                    return url, timestamp, error_text
                else:
                    error_text += (
                        f"Fant ikke bilde med {valid_args_fmt}. "
                        "Her er et tilfeldig bilde i stedet:"
                    )
            else:
                error_text += "Her er et tilfeldig bilde i stedet:"

        sql_command = (
            'SELECT path, taken FROM dbx_pictures '
            'WHERE topic = %(topic)s ORDER BY RAND() LIMIT 1'
        )
        data = {"topic": random.choice(list(self.topics))}

        cursor.execute(sql_command, data)
        path, date_obj = cursor.fetchone()
        url = self.get_url(path)
        timestamp = self.get_timestamp(date_obj)

        return url, timestamp, error_text


if __name__ == "__main__":
    db_connection = database_manager.connect_to_database()
    drop_pics = DropPics(db=db_connection)
    drop_pics.connect_dbx()
    # drop_pics.db_setup()
    try:
        log.info(drop_pics.get_pic(*[]))

        topics = list(drop_pics.topics)
        for topic in topics[0:2]:
            log.info(drop_pics.get_pic(*[topic]))

        years = list(drop_pics.years)
        for year in years[0:2]:
            log.info(drop_pics.get_pic(*[year]))

        users = list(config.slack_nicks_to_garg_ids.keys())
        for user in users[0:2]:
            log.info(drop_pics.get_pic(*[user]))

        all_args = [topics, years, users]
        for permutation in list(itertools.product(*all_args),)[0:2]:
            log.info(drop_pics.get_pic(*permutation))

        # Errors:
        log.info(drop_pics.get_pic(*["2000"]))

        log.info(drop_pics.get_pic(*["2000", users[0]]))
    finally:
        db_connection.close()

@@ -95,26 +95,8 @@
 me%0D%0A
-import itertools%0D%0A
 impo
@@ -147,33 +147,8 @@
 ig%0D%0A
-import database_manager%0D%0A
 %0D%0A%0D%0A
@@ -4886,992 +4886,4 @@
 xt%0D%0A
-%0D%0A%0D%0Aif __name__ == %22__main__%22:%0D%0A    db_connection = database_manager.connect_to_database()%0D%0A    drop_pics = DropPics(db=db_connection)%0D%0A    drop_pics.connect_dbx()%0D%0A    # drop_pics.db_setup()%0D%0A    try:%0D%0A        log.info(drop_pics.get_pic(*%5B%5D))%0D%0A%0D%0A        topics = list(drop_pics.topics)%0D%0A        for topic in topics%5B0:2%5D:%0D%0A            log.info(drop_pics.get_pic(*%5Btopic%5D))%0D%0A%0D%0A        years = list(drop_pics.years)%0D%0A        for year in years%5B0:2%5D:%0D%0A            log.info(drop_pics.get_pic(*%5Byear%5D))%0D%0A%0D%0A        users = list(config.slack_nicks_to_garg_ids.keys())%0D%0A        for user in users%5B0:2%5D:%0D%0A            log.info(drop_pics.get_pic(*%5Buser%5D))%0D%0A%0D%0A        all_args = %5Btopics, years, users%5D%0D%0A        for permutation in list(itertools.product(*all_args),)%5B0:2%5D:%0D%0A            log.info(drop_pics.get_pic(*permutation))%0D%0A%0D%0A        # Errors:%0D%0A        log.info(drop_pics.get_pic(*%5B%222000%22%5D))%0D%0A%0D%0A        log.info(drop_pics.get_pic(*%5B%222000%22, users%5B0%5D%5D))%0D%0A    finally:%0D%0A        db_connection.close()%0D%0A

remove manual testing vestinges