#!/usr/bin/env python3

'''
manowar_saltcell

A cli agent to help run the saltcell agent. Handles reding configs from file and printing and shit.
'''

# Salt Cell

import os
import logging

import yaml
import requests
import sys
import argparse
import json

#import salt.config
#import salt.client

from saltcell.clientcollector import Host

#
# Process
# 1. Grab Configs
# 1. Grab Collection Configuration
# 1. Do Collection
# 1. Submit Results
#
#

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-c", "--config", help="Stingcell Config File (Default etc/manowar_agent/saltcell.yaml)", default=False)
    parser.add_argument("-p", "--print", help="Print stingcell json to stdout in addition to sending it along.", action='store_true')
    parser.add_argument("-n", "--noupload", help="Do not upload results to endoint.", action='store_true')
    parser.add_argument("-v", "--verbose", action='append_const', help="Turn on Verbosity", const=1, default=[])
    parser._optionals.title = "DESCRIPTION "

    # Parser Args
    args = parser.parse_args()

    VERBOSE = len(args.verbose)

    if VERBOSE == 0:
        logging.basicConfig(level=logging.ERROR)

    elif VERBOSE == 1:
        logging.basicConfig(level=logging.WARNING)

    elif VERBOSE == 2:
        logging.basicConfig(level=logging.INFO)

    else:
        logging.basicConfig(level=logging.DEBUG)

    logger = logging.getLogger("saltcell.py")

    logger.info("Welcome to Saltcell")

    CONFIG_FILE=args.config

    if args.config is False:
        logger.debug("No Config File Given Look in Default Locations")
        for default_file in ("/etc/manowar_agent/saltcell.yaml",
                             "./etc/manowar_agent/saltcell.yaml",
                             "./saltcell.yaml",
                             "/usr/local/etc/manowar_agent/saltcell.yaml"):

            if os.path.isfile(default_file) and os.access(default_file, os.R_OK):
                logger.debug("Using Default File : {}".format(default_file))
                CONFIG_FILE = default_file
                # Found a good file, us it.
                break

    if CONFIG_FILE is not False:
        with open(CONFIG_FILE, "r") as config_file:
            try:
                configs = yaml.safe_load(config_file)
            except yaml.YAMLError as parse_error:
                logger.error("Unable to parse file {} with error : \n {}".format(CONFIG_FILE, parse_error))
                sys.exit(1)
            else:
                logger.debug("Loaded Configurations from {}".format(CONFIG_FILE))
            finally:
                # Let's Find my Minion File
                if configs.get("salt", {}).get("minion_file", False) is False:
                    # Minion File Is Not Specified Choose Default
                    minion_defaults = [os.path.dirname(os.path.realpath(CONFIG_FILE)) + "/minion",
                                       "/etc/manowar_agent/minion",
                                       "/usr/local/etc/manowar_agent/minion",
                                       "/etc/salt/minion",
                                       "./minion",
                                       "./etc/manowar_agent/minion",
                                       "/usr/etc/salt/minion"]

                    for possible_minion in minion_defaults:
                        if os.path.isfile(possible_minion) and os.access(possible_minion, os.R_OK):
                            logger.debug("Using Minion File : {}".format(possible_minion))
                            configs["salt"] = {"minion_file" : possible_minion}
                            break

                    if configs.get("salt", {}).get("minion_file", False) is False:
                        logger.error("minion_file not specified in config and default minion file not found. Erroring.")
                        sys.exit(1)
                else:
                    logger.debug("Minion File Specified in Config, utilizing that file.")

                # Let's Find my Collector Configuration File
                if configs.get("stingcell", {}).get("collection_config_file", False) is False:
                    collector_defaults = [os.path.dirname(os.path.realpath(CONFIG_FILE)) + "/collector.yaml",
                                          "/etc/manowar_agent/collector.yaml",
                                          "./collector.yaml",
                                          "./etc/manowar_agent/collector.yaml",
                                          "/usr/local/etc/manowar_agent/collector.yaml"]

                    for possible_collector in collector_defaults:
                        if os.path.isfile(possible_collector) and os.access(possible_collector, os.R_OK):
                            logger.debug("Using Collector File : {}".format(possible_collector))
                            configs["stingcell"]["collection_config_file"] = possible_collector
                            break
                else:
                    logger.debug("Collector File Specified in Config, utilizing that file.")

    else:
        logger.error("No Config File Specifed or Found. Exiting.")
        sys.exit(1)

    if args.print:
        PRINT = True
    else:
        PRINT = False

    if args.noupload:
        NOUPLOAD = True
    else:
        NOUPLOAD = False


def docoll(config_items=False, noupload=False) :

    """
    docoll Does the actual collection fo the things
    """

    logger = logging.getLogger("saltcell.docoll")


    # Step 2 Grab Collection Configuration
    collection_configuration_file = config_items["stingcell"]["collection_config_file"]

    this_host = Host(minion_file=config_items["salt"].get("minion_file", "minion"), \
                     base_config_file=config_items["stingcell"]["collection_config_file"], \
                     local_cols=(config_items["stingcell"].get("local_collections", False), \
                                 config_items["stingcell"].get("local_collections_location", "/etc/manowar_agent/collections.d")),
                     host_configs=config_items["hostinfo"],
                     ipintel_configs=config_items["ipintel"],
                     noupload=NOUPLOAD,
                     sapi_configs=config_items.get("sapi", {"sapi_do_api" : False}))

    return this_host.todict()

if __name__ == "__main__":
    collection_data = docoll(config_items=configs)

    if PRINT == True:
        sys.stdout.write(json.dumps(collection_data, default=str))
