# -*- coding: utf-8 -*-

import os
import sys
import fcntl
import signal
import logging
import logging.config

from ConfigParser import ConfigParser

from openprocurement.search.version import __version__
from openprocurement.search.engine import IndexEngine, logger
from openprocurement.search.utils import decode_bool_values

from openprocurement.search.source.orgs import OrgsSource
from openprocurement.search.index.orgs import OrgsIndex

from openprocurement.search.source.tender import TenderSource
from openprocurement.search.index.tender import TenderIndex

from openprocurement.search.source.ocds import OcdsSource
from openprocurement.search.index.ocds import OcdsIndex

from openprocurement.search.source.plan import PlanSource
from openprocurement.search.index.plan import PlanIndex

from openprocurement.search.source.auction import AuctionSource, AuctionSource2
from openprocurement.search.index.auction import AuctionIndex, AuctionIndex2

from openprocurement.search.source.asset import AssetSource
from openprocurement.search.index.asset import AssetIndex

from openprocurement.search.source.dgf_lot import DgfLotSource
from openprocurement.search.index.dgf_lot import DgfLotIndex


engine = type('engine', (), {})()


def sigterm_handler(signo, frame):
    logger.info("Signal received %d", signo)
    if engine and hasattr(engine, 'stop_childs'):
        engine.should_exit = True
        engine.stop_childs()
    signal.alarm(3)
    # sys.exit(0)


def main():
    if len(sys.argv) < 2:
        print("Usage: index_worker etc/search.ini [custom_index_names_file]")
        sys.exit(1)

    parser = ConfigParser()
    parser.read(sys.argv[1])
    config = dict(parser.items('search_engine'))
    config = decode_bool_values(config)

    # disable slave mode if used custom_index_names
    if len(sys.argv) > 2:
        config['index_names'] = sys.argv[2]
        config['slave_mode'] = ''
        config['start_wait'] = 0

    logging.config.fileConfig(sys.argv[1])

    logger.info("Starting ProZorro openprocurement.search.index_worker v%s", __version__)
    logger.info("Copyright (c) 2015-2016 Volodymyr Flonts <flyonts@gmail.com>")

    # try get exclusive lock to prevent second start
    lock_filename = config.get('index_names', 'index_worker') + '.lock'
    lock_file = open(lock_filename, "w")
    try:
        fcntl.lockf(lock_file, fcntl.LOCK_EX + fcntl.LOCK_NB)
        lock_file.write(str(os.getpid()) + "\n")
        lock_file.flush()
    except:
        logger.error("Can't get lock %s maybe already started",
            lock_filename)
        lock_file.close()
        return 1

    signal.signal(signal.SIGTERM, sigterm_handler)
    # signal.signal(signal.SIGINT, sigterm_handler)

    try:
        global engine
        engine = IndexEngine(config)
        if config.get('orgs_db', None):
            source = OrgsSource(config)
            OrgsIndex(engine, source, config)
        if config.get('tender_api_url', None):
            source = TenderSource(config)
            TenderIndex(engine, source, config)
        if config.get('ocds_dir', None):
            source = OcdsSource(config)
            OcdsIndex(engine, source, config)
        if config.get('plan_api_url', None):
            source = PlanSource(config)
            PlanIndex(engine, source, config)
        if config.get('auction_api_url', None):
            source = AuctionSource(config)
            AuctionIndex(engine, source, config)
        if config.get('auction2_api_url', None):
            source = AuctionSource2(config)
            AuctionIndex2(engine, source, config)
        if config.get('asset_api_url', None):
            source = AssetSource(config)
            AssetIndex(engine, source, config)
        if config.get('lot_api_url', None):
            source = DgfLotSource(config)
            DgfLotIndex(engine, source, config)
        engine.run()
    except Exception as e:
        logger.exception("Unhandled Exception: %s", str(e))
    finally:
        lock_file.close()
        os.remove(lock_filename)
        if engine and hasattr(engine, 'stop_childs'):
            engine.stop_childs()
        logger.info("Shutdown")

    return 0


if __name__ == "__main__":
    main()

@@ -1457,24 +1457,843 @@
 s.exit(0)%0A%0A%0A
+def chage_process_user_group(config):%0A    from pwd import getpwuid, getpwnam%0A    from grp import getgrgid, getgrnam%0A    if config.get('user', ''):%0A        uid = os.getuid()%0A        newuid = getpwnam(config%5B'user'%5D)%5B2%5D%0A        if uid != newuid:%0A            if uid != 0:%0A                logger.error(%22Can't change user not from root%22)%0A                return%0A            if config.get('group', ''):%0A                newgid = getgrnam(config%5B'group'%5D)%5B2%5D%0A                os.setgid(newgid)%0A            os.setuid(newuid)%0A    uid = os.getuid()%0A    gid = os.getgid()%0A    euid = os.geteuid()%0A    egid = os.getegid()%0A    logger.info(%22Process real user/group %25d/%25d %25s/%25s%22, uid, gid, getpwuid(uid)%5B0%5D, getgrgid(gid)%5B0%5D)%0A    logger.info(%22Process effective user/group %25d/%25d %25s/%25s%22, euid, egid, getpwuid(euid)%5B0%5D, getgrgid(egid)%5B0%5D)%0A%0A%0A
 def main():%0A
@@ -2965,24 +2965,164 @@
 ail.com%3E%22)%0A%0A
+    try:%0A        chage_process_user_group(config)%0A    except Exception as e:%0A        logger.error(%22Can't change process user: %25s%22, str(e))%0A%0A
     # try ge

add chage_process_user_group for index_worker