from elasticsearch import Elasticsearch as Es
from elasticsearch import helpers


def es_index_adapt(index_prefix, doc_type, rw=None):
    """get the adapted index name
    """
    assert rw in [None, "read", "write"]
    index = "-".join((index_prefix, doc_type))
    if rw:
        index = "-".join((index, rw))
    return index


def get_es(is_es7=False, es_router_key="default"):
    init_args = {
        "sniff_on_start": False,
        "sniff_on_connection_fail": False,
    }
    new_hosts = [{
        "host": "172.16.31.17",
        "port": 9000,
    }, {
        "host": "172.16.31.11",
        "port": 9000,
    }, {
        "host": "172.16.31.13",
        "port": 9000,
    }]
    if is_es7:
        clusters = {
            "content": ["172.16.52.33:9200", "172.16.52.19:9200", "172.16.52.27:9200", "172.16.52.34:9200", "172.16.52.48:9200"],
            "service": ["172.16.52.25:9200", "172.16.52.36:9200", "172.16.52.26:9200"]
        }
        es_router = {"default": "content", "diary": "content", "service": "service", "tractate": "content", "answer": "content"}
        http_auth = ("elastic", "gengmei!@#")
        new_es = Es(hosts=clusters[es_router[es_router_key]], http_auth=http_auth, **init_args)
    else:
        new_es = Es(hosts=new_hosts, **init_args)
    return new_es


def es_query(doc, body, offset=0, size=100, es=None, rw="read", is_es7=False, es_router_key="default"):
    if es is None:
        es = get_es(is_es7=is_es7, es_router_key=es_router_key)
    index = es_index_adapt(index_prefix="gm-dbmw", doc_type=doc, rw=rw)
    res = es.search(index=index, timeout="2s", body=body, from_=offset, size=size)
    return res


def es_msearch(query_body, es=None, es_router_key="default"):
    if es is None:
        es = get_es(is_es7=True, es_router_key=es_router_key)
    res = es.msearch(query_body)
    return res


def es_scan(doc, body, es=None, rw="read", is_es7=False, es_router_key="default"):
    if es is None:
        es = get_es(is_es7=is_es7, es_router_key=es_router_key)
    index = es_index_adapt(index_prefix="gm-dbmw", doc_type=doc, rw=rw)
    return helpers.scan(es, index=index, query=body, request_timeout=100, scroll="300m", raise_on_error=False)


# curl "http://172.16.31.17:9000/gm-dbmw-tractate-read/_search?pretty&size=1" -d '
# '
def get_tractate_info_from_es(fields=["id"]):
    q = {
        "query": {
            "bool": {
                "must": [{
                    "term": {
                        "is_online": "true"
                    }
                }, {
                    "terms": {
                        "content_level": [6, 5, 4, 3.5, 3]
                    }
                }],
                "must_not": [{
                    "term": {
                        "status": 4
                    }
                }, {
                    "term": {
                        "show_by_index": 2
                    }
                }]
            }
        },
        "_source": {
            "include": fields
        }
    }
    results = es_scan("tractate", q)
    return results


def get_answer_info_from_es(fields=["id"]):
    q = {
        "query": {
            "bool": {
                "must": [{
                    "term": {
                        "is_online": True
                    }
                }, {
                    "terms": {
                        "content_level": [6, 5, 4, 3.5, 3]
                    }
                }, {
                    "range": {
                        "content_length": {
                            "gte": 30
                        }
                    }
                }]
            }
        },
        "_source": {
            "include": fields
        }
    }
    results = es_scan("answer", q)
    return results


def get_diary_info_from_es(fields=["id"]):
    q = {
        "query": {
            "bool": {
                "filter": [{
                    "term": {
                        "is_online": True
                    }
                }, {
                    "term": {
                        "has_cover": True
                    }
                }, {
                    "term": {
                        "is_sink": False
                    }
                }, {
                    "term": {
                        "has_before_cover": True
                    }
                }, {
                    "term": {
                        "has_after_cover": True
                    }
                }, {
                    "terms": {
                        "content_level": [6, 5, 4, 3.5, 3]
                    }
                }, {
                    "term": {
                        "content_simi_bol_show": 0
                    }
                }, {
                    "exists": {
                        "field": "before_cover_url"
                    }
                }]
            }
        },
        "_source": {
            "include": fields
        }
    }
    results = es_scan("diary", q)
    return results


def get_online_ids(content_type):
    q = {"query": {"bool": {"must": [{"term": {"is_online": True}}]}}}
    results = es_scan(content_type, q)
    return results


def get_tag3_info_from_content(id, es_doc_name, action=""):
    first_demands = []
    second_demands = []
    first_solutions = []
    second_solutions = []
    first_positions = []
    second_positions = []
    projects = []
    anecdote_tags = []
    gossip_tags = []
    business_tags = []
    fields = [
        "first_demands", "second_demands", "first_solutions", "second_solutions", "positions", "second_positions", "tags_v3",
        "anecdote_tags", "portrait_tag_name"
    ]
    if es_doc_name in ["answer", "tractate"]:
        fields.append("gossip_tags")
    q = {"query": {"term": {"id": id}}, "_source": {"includes": fields}}
    try:
        es_res = es_query(es_doc_name, q, is_es7=True)
        hits = es_res["hits"]["hits"]
        for hit in hits:
            first_demands = hit["_source"].get("first_demands", [])
            second_demands = hit["_source"].get("second_demands", [])
            first_solutions = hit["_source"].get("first_solutions", [])
            second_solutions = hit["_source"].get("second_solutions", [])
            first_positions = hit["_source"].get("positions", [])
            second_positions = hit["_source"].get("second_positions", [])
            projects = hit["_source"].get("tags_v3", [])
            anecdote_tags = hit["_source"].get("anecdote_tags", [])
            business_tags = hit["_source"].get("portrait_tag_name", [])
            gossip_tags = hit["_source"].get("gossip_tags", [])

        res = {
            "action": action,
            "es_doc_name": es_doc_name,
            "first_demands": first_demands,
            "second_demands": second_demands,
            "first_solutions": first_solutions,
            "second_solutions": second_solutions,
            "first_positions": first_positions,
            "second_positions": second_positions,
            "projects": projects,
            "anecdote_tags": anecdote_tags,
            "business_tags": business_tags,
            "gossip_tags": gossip_tags
        }
        return res
    except Exception as e:
        res = {
            "action": action,
            "es_doc_name": es_doc_name,
            "first_demands": first_demands,
            "second_demands": second_demands,
            "first_solutions": first_solutions,
            "second_solutions": second_solutions,
            "first_positions": first_positions,
            "second_positions": second_positions,
            "projects": projects,
            "anecdote_tags": anecdote_tags,
            "business_tags": business_tags,
            "gossip_tags": gossip_tags
        }
        return res
