#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
 #the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import sys
import threading
import multiprocessing
import yaml
import json
import time
import re
import argparse
import plugins.scanners
import plugins.brokers.kibbleES
#import plugins.kibbleJSON

VERSION = "0.1.0"
CONFIG_FILE = "conf/config.yaml"
PENDING_OBJECTS = []
BIG_LOCK = threading.Lock()

def base_parser():
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument("-o", "--org", help="The organisation to gather stats for. If left out, all organisations will be scanned.")
    arg_parser.add_argument("-f", "--config", help="Location of the yaml config file (full path)")
    arg_parser.add_argument("-a", "--age", help="Minimum age in hours before performing a new scan on an already processed source. --age 12 will not process any source that was processed less than 12 hours ago, but will process new sources.")
    arg_parser.add_argument("-s", "--source", help="A specific source (wildcard) to run scans on.")
    arg_parser.add_argument("-n", "--nodes", help="Number of nodes in the cluster (used for load balancing)")
    arg_parser.add_argument("-t", "--type", help="Specific type of scanner to run (default is run all scanners)")
    arg_parser.add_argument("-v", "--view", help="Specific source view to scan (default is scan all sources)")
    return arg_parser
   
def pprint(string, err = False):
    line = "[core]: %s" % (string)
    if err:
        sys.stderr.write(line + "\n")
    else:
        print(line)
        

def isMine(ID, config):
    if config['scanner'].get('balance',  None):
        a = config['scanner']['balance'].split('/')
        nodeNo = int(a[0])
        numNodes = int(a[1])
        if numNodes == 0:
            return True
        bignum = int(ID, 16) % numNodes
        if bignum == int(nodeNo)-1:
            return True
        return False
    return True
    
class scanThread(threading.Thread):
    """ A thread object that grabs an item from the queue and processes
        it, using whatever plugins will come out to play. """
    def __init__(self, broker, org, i, t = None):
        super(scanThread, self).__init__()
        self.broker = broker
        self.org = org
        self.id = i
        self.bit = self.broker.bitClass(self.broker, self.org, i)
        self.stype = t
        pprint("Initialized thread %i" % i)
    
    def run(self):
        global BIG_LOCK, PENDING_OBJECTS
        time.sleep(0.5) # Primarily to align printouts.
        # While there are objects to snag
        a = 0
        while PENDING_OBJECTS:
            BIG_LOCK.acquire(blocking = True)
            try:
                # Try grabbing an object (might not be any left!)
                obj = PENDING_OBJECTS.pop(0)
            except:
                pass
            BIG_LOCK.release()
            if obj:
                # If load balancing jobs, make sure this one is ours
                if isMine(obj['sourceID'], self.broker.config):
                    # Run through list of scanners in order, apply when useful
                    for sid, scanner in plugins.scanners.enumerate():
                        
                        if scanner.accepts(obj):
                            self.bit.pluginname = "plugins/scanners/" + sid
                            if not self.stype or self.stype == sid:
                                scanner.scan(self.bit, obj)
            else:
                break
        self.bit.pluginname = "core"
        self.bit.pprint("No more objects, exiting!")

def main():
    pprint("Kibble Scanner v/%s starting" % VERSION)
    global CONFIG_FILE, PENDING_OBJECTS
    args = base_parser().parse_args()
    
    # Load config yaml
    if args.config:
        CONFIG_FILE = args.config
    config = yaml.load(open(CONFIG_FILE))
    pprint("Loaded YAML config from %s" % CONFIG_FILE)
    
    # Which broker type do we use here?
    broker = None
    if 'elasticsearch' in config and config['elasticsearch'].get('enabled', False):
        pprint("Using direct ElasticSearch broker model")
        broker = plugins.brokers.kibbleES.Broker(config)
    else:
        pprint("Using HTTP JSON broker model")
        broker = plugins.brokers.kibbleJSON.Broker(config)
    
    orgNo = 0
    sourceNo = 0
    for org in broker.organisations():
        if not args.org or args.org == org.id:
            pprint("Processing organisation %s" % org.id)
            orgNo += 1
            
            # Compile source list
            # If --age is passed, only append source that either
            # have never been scanned, or have been scanned more than
            # N hours ago by any scanner.
            if args.age:
                minAge = time.time() - int(args.age) * 3600
                for source in org.sources(view=args.view):
                    tooNew = False
                    if 'steps' in source:
                        for key, step in source['steps'].items():
                            if 'time' in step and step['time'] >= minAge:
                                tooNew = True
                                break
                    if not tooNew:
                        if not args.source or (args.source == source['sourceID']):
                            PENDING_OBJECTS.append(source)
            else:
                PENDING_OBJECTS = []
                for source in org.sources(view=args.view):
                    if not args.source or (args.source == source['sourceID']):
                        PENDING_OBJECTS.append(source)
                sourceNo += len(PENDING_OBJECTS)
            
            # Start up some threads equal to number of cores on the box,
            # but no more than 4. We don't want an IOWait nightmare.
            threads = []
            core_count = min((4, int( multiprocessing.cpu_count() )))
            for i in range(0, core_count):
                sThread = scanThread(broker, org, i+1, args.type)
                sThread.start()
                threads.append(sThread)
            
            # Wait for them all to finish.
            for t in threads:
                t.join()
        
    pprint("All done scanning for now, found %i organisations and %i sources to process." % (orgNo, sourceNo))
    
if __name__ == '__main__':
    main()
