# -*- coding: UTF-8 -*-
import os

from django.core.management import BaseCommand
from gm_dbmw_api.descriptor import *
from injection.data_sync.core import data
from injection.data_sync.core import django_data
from injection.data_sync.impl.connections.connection import get_data_source, get_data_source_config

TABLE_EXCLUDED_COLUMNS_MAP = {
    '"api_doctor': [
        'view_num',
        'reply_num',
        'new_pm_num',
        'reply_pm_num',
        'no_reply_pm_num',
        'share_topic_num',
        'last_answered_time',
    ],
}

MIMAS_TABLES = [
    "api_topicvote",
    "api_diaryoperate",
    "api_diaryfavor",
    "api_live_stream",
    "api_problemtag",
    "api_topicreply",
    "api_reply_collect",
    "api_columntabtag",
    "api_votepk",
    "api_wechatmaterial",
    "api_topicreplyvote",
    "api_live_white_list",
    "api_video_white_list",
    "api_problemfavor",
    "api_diary",
    "api_pgcclassify",
    "api_article",
    "api_live_msg",
    "api_topicrankingscore",
    "api_topicimage",
    "api_streamtag",
    "api_diarycheck",
    "api_diaryvote",
    "api_columnist",
    "api_preoperationimage",
    "api_problem_operations",
    "api_activity",
    "api_replyheadline",
    "api_problem",
    "api_live_channel",
    "api_columntab",
    "api_diarymessage",
    "api_columncard",
    "api_zhiboconfig",
    "api_diary_tags",
    "api_topic_video",
    "api_draft",
    "api_diaryrank",
    "api_topicscore",
    "api_activitywinlist",
    "api_report",
    "api_filterword",

    "community_article",
    "community_topic_sticky",

    "relation_usertagrelation",
    "social_userfollow",
    "social_feed",

    "api_question_vote",
    "api_questiontag",
    "api_question",
    "api_answer_vote",
    "api_overheadquestion",
    "api_question_image",
    "api_answer_top",
    "api_answerreply_vote",
    "api_answer",
    "api_answer_reply",
    "api_overheadanswer",
    "api_answer_image",
    "api_user_question_answer",
]


def trans_data_source(ds):
    if isinstance(ds, source.Source):
        return ds
    if type(ds) == django_data.ModelDataSource:
        return """source.MySQLTableSource(
            logical_database_id=settings.{}_LOGICAL_DATABASE_ID,
            table_name="{}",
            key_columns=['id'],
            value_columns_excluded={},
            value_columns_all=True,
        )""".format(
            "MIMAS" if ds.table_name in MIMAS_TABLES else "DBMW",
            ds.table_name,
            TABLE_EXCLUDED_COLUMNS_MAP.get(ds.table_name, [])
        )
    elif type(ds) == data.RelatedDataSource:
        rel = trans_relations(ds.data_relation)
        rds = trans_data_source(ds.secondary_data_source)
        rds = """source.RelatedSource(
            source={rds},
            relation={rel}
        )""".format(rds=rds, rel=rel)
        return rds
    elif type(ds) in (data.GroupedDataSource, data.JoinedDataSource):
        return """source.GroupedSource.of(
        {}
        )""".format(",\n".join(trans_data_source(member) for member in ds._args + tuple(ds._kwargs.values())))

    elif type(ds) == data.EmptyDataSource:
        return "source.NullSource()"

    else:
        raise Exception('???')


def trans_relations(rel):
    if type(rel) == django_data.ReversedDataRelation:
        return do_trans_relations(rel._rev, is_reversed=True)
    else:
        return do_trans_relations(rel, is_reversed=False)


def do_trans_relations(rel, is_reversed=False):
    if type(rel) == django_data.ForeignKeyDataRelation:
        if not is_reversed:
            return """relation.MySQLTableRelation(
                logical_database_id=settings.{}_LOGICAL_DATABASE_ID,
                table_name="{}",
                from_columns=["{}"],
                to_columns=["{}"],
            )""".format(
            "MIMAS" if rel.table_name in MIMAS_TABLES else "DBMW",
                rel.table_name, 
                rel.fk_attname, 
                rel.pk_attname
            )
        else:
            return """relation.MySQLTableRelation(
                logical_database_id=settings.{}_LOGICAL_DATABASE_ID,
                table_name="{}",
                from_columns=["{}"],
                to_columns=["{}"],
            )""".format(
            "MIMAS" if rel.table_name in MIMAS_TABLES else "DBMW",
                rel.table_name, rel.pk_attname, rel.fk_attname)
    elif type(rel) == django_data.M2MDataRelation:
        assert not is_reversed
        assert isinstance(rel, django_data.M2MDataRelation)
        return """relation.MySQLTableRelation(
            logical_database_id=settings.{}_LOGICAL_DATABASE_ID,
            table_name="{}",
            from_columns=["{}"],
            to_columns=["{}"],
        )""".format(
            "MIMAS" if rel.through_table_name in MIMAS_TABLES else "DBMW",rel.through_table_name, rel.secondary_attname, rel.primary_attname)


VALID_CONFIGURATION_SET = [
    'pk_data_source',
    'index_data_source',
]


class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument('-sp', '--store-path', dest='path')
        parser.add_argument('--supervisor-conf-path')
        parser.add_argument('--queue-name')

    def handle(self, *args, **options):
        if not os.path.exists("connections"):
            os.mkdir("connections")
        common = """# coding=utf-8
from django.conf import settings
from gm_dbmw_api.descriptor import source, relation


"""
        for name, type_info in get_data_source_config().items():
            with open("connections/{}.py".format(name), "w") as f:
                f.write(common)
                for configuration in VALID_CONFIGURATION_SET:
                    print name, configuration
                    s = trans_data_source(get_data_source(type_info.name, configuration))

                    f.write("{}={}".format(configuration, s))
