# Path: database/memory_db.py
# class MemoryDB():
#     def __init__(self):
#         path = os.path.dirname(__file__)
# 
#         indexed_path = os.path.join(path, "indexed.idx")
#         exports_path = os.path.join(path, "exports.idx")
#         with open(indexed_path, 'r') as index_file:
#             self.indexes = json.load(index_file)
#         with open(exports_path, 'r') as export_file:
#             self.data = json.load(export_file)
# 
#     def query(self, product, version):
#         index = str((product, version))
#         output = []
#         for idx in self.indexes[index]:
#             output.append(self.data[idx])
#         return output
# 
#     def get_privileges(self, product, version):
#         """ Returns a list of (CSV, admin)"""
# 
#         def filter_by_field(data, field):
#             if not field in data:
#                 return None
#             return data[field]
# 
#         def parse_metric_v2(impact):
#             impact = filter_by_field(impact, "baseMetricV2")
#             if impact is None:
#                 return None
#             if not "userInteractionRequired" in impact:
#                 return None
#             if impact["userInteractionRequired"]:
#                 return None
#             return {
#                 "all" : impact["obtainAllPrivilege"],
#                 "user" : impact["obtainUserPrivilege"],
#                 "other" : impact["obtainOtherPrivilege"]
#             }
# 
#         vulenerability_list = self.query(product, version)
#         levels = []
#         for vulnerability in vulenerability_list:
#             if "impact" in vulnerability:
#                 v2_out = parse_metric_v2(vulnerability["impact"])
#                 if v2_out is not None:
#                     levels.append(v2_out)
#                 else:
#                     levels.append({"unknown" : True})
#             else:
#                 levels.append({"unknown" : True})
# 
#         return levels
# 
# Path: service/server.py
# class Server():
#     def __init__(self, name, port):
#     def add_component_post(self, route, component):
#         def binder():
#             def binded():
#     def add_component_get(self, route, component):
#         def binder():
#             def binded():
#     def run(self):
# 
# Path: service/server.py
# class Server():
#     """
#     A server builder class.
# 
#     Each server is extendable via adding restful components.
#     The underlying server is Flask.
# 
#     e.g.
#       Server("test_server", "30020")
#         .add_component_get("/get_route", get_component)
#         .add_component_post("/post_route", post_component)
#         .run()
#     """
#     def __init__(self, name, port):
#         self.app = Flask(name)
#         self.name = name
#         self.port = port
#         self.components = []
# 
#     def add_component_post(self, route, component):
#         self.components.append(component)
# 
#         def binder():
#             def binded():
#                 return component.receive_post()
#             binded.__name__ = self.name + route.replace("/", "_")
# 
#             return binded
# 
#         self.app.route(route, methods=['POST'])(binder())
#         return self
# 
#     def add_component_get(self, route, component):
#         self.components.append(component)
# 
#         def binder():
#             def binded():
#                 return component.receive_get()
#             binded.__name__ = self.name + route.replace("/", "_")
# 
#             return binded
# 
#         self.app.route(route, methods=['GET'])(binder())
#         return self
# 
#     def run(self):
#         self.app.run(host='0.0.0.0', port=int(self.port))
# 
# Path: service/components.py
# class Component():
#     __metaclass__ = abc.ABCMeta
#     """
#     A component class that receives JSON requests and returns stringyfied jsons.
# 
#     To implement a new component, extend this class.
#     """
# 
#     @abc.abstractmethod
#     def process(self, json):
#         pass
# 
#     def receive_post(self):
#         if request.method == "POST":
#             req = request.get_json()
#             output = self.process(req)
#             return str(output)
# 
#     def receive_get(self):
#         if request.method == "GET":
#             output = self.process("")
#             return str(output)
# 
# Path: service/client.py
# class LocalClient(Client):
#     def __init__(self, port):
#         self._url = "http://127.0.0.1"
#         self._port = port


import logging
import os, sys, time
import ast
from database.memory_db import MemoryDB
from service.server import config
from service.server import Server
from service.components import Component
from service.client import LocalClient
from __future__ import absolute_import

logger = logging.getLogger(__name__)

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))



class DBQuery(Component):
    def __init__(self, db):
        self.db = db

    def process(self, json):
        output = {}
        try:
            output = self.db.query(json["product"], json["version"])
            logger.info("DB found: {} {}".format(json["product"], json["version"]))
        except Exception as e:
            logger.warn("DB miss: {} {}".format(json["product"], json["version"]))
        return output


# Path: database/memory_db.py
# class MemoryDB():
#     def __init__(self):
#         path = os.path.dirname(__file__)
# 
#         indexed_path = os.path.join(path, "indexed.idx")
#         exports_path = os.path.join(path, "exports.idx")
#         with open(indexed_path, 'r') as index_file:
#             self.indexes = json.load(index_file)
#         with open(exports_path, 'r') as export_file:
#             self.data = json.load(export_file)
# 
#     def query(self, product, version):
#         index = str((product, version))
#         output = []
#         for idx in self.indexes[index]:
#             output.append(self.data[idx])
#         return output
# 
#     def get_privileges(self, product, version):
#         """ Returns a list of (CSV, admin)"""
# 
#         def filter_by_field(data, field):
#             if not field in data:
#                 return None
#             return data[field]
# 
#         def parse_metric_v2(impact):
#             impact = filter_by_field(impact, "baseMetricV2")
#             if impact is None:
#                 return None
#             if not "userInteractionRequired" in impact:
#                 return None
#             if impact["userInteractionRequired"]:
#                 return None
#             return {
#                 "all" : impact["obtainAllPrivilege"],
#                 "user" : impact["obtainUserPrivilege"],
#                 "other" : impact["obtainOtherPrivilege"]
#             }
# 
#         vulenerability_list = self.query(product, version)
#         levels = []
#         for vulnerability in vulenerability_list:
#             if "impact" in vulnerability:
#                 v2_out = parse_metric_v2(vulnerability["impact"])
#                 if v2_out is not None:
#                     levels.append(v2_out)
#                 else:
#                     levels.append({"unknown" : True})
#             else:
#                 levels.append({"unknown" : True})
# 
#         return levels
# 
# Path: service/server.py
# class Server():
#     def __init__(self, name, port):
#     def add_component_post(self, route, component):
#         def binder():
#             def binded():
#     def add_component_get(self, route, component):
#         def binder():
#             def binded():
#     def run(self):
# 
# Path: service/server.py
# class Server():
#     """
#     A server builder class.
# 
#     Each server is extendable via adding restful components.
#     The underlying server is Flask.
# 
#     e.g.
#       Server("test_server", "30020")
#         .add_component_get("/get_route", get_component)
#         .add_component_post("/post_route", post_component)
#         .run()
#     """
#     def __init__(self, name, port):
#         self.app = Flask(name)
#         self.name = name
#         self.port = port
#         self.components = []
# 
#     def add_component_post(self, route, component):
#         self.components.append(component)
# 
#         def binder():
#             def binded():
#                 return component.receive_post()
#             binded.__name__ = self.name + route.replace("/", "_")
# 
#             return binded
# 
#         self.app.route(route, methods=['POST'])(binder())
#         return self
# 
#     def add_component_get(self, route, component):
#         self.components.append(component)
# 
#         def binder():
#             def binded():
#                 return component.receive_get()
#             binded.__name__ = self.name + route.replace("/", "_")
# 
#             return binded
# 
#         self.app.route(route, methods=['GET'])(binder())
#         return self
# 
#     def run(self):
#         self.app.run(host='0.0.0.0', port=int(self.port))
# 
# Path: service/components.py
# class Component():
#     __metaclass__ = abc.ABCMeta
#     """
#     A component class that receives JSON requests and returns stringyfied jsons.
# 
#     To implement a new component, extend this class.
#     """
# 
#     @abc.abstractmethod
#     def process(self, json):
#         pass
# 
#     def receive_post(self):
#         if request.method == "POST":
#             req = request.get_json()
#             output = self.process(req)
#             return str(output)
# 
#     def receive_get(self):
#         if request.method == "GET":
#             output = self.process("")
#             return str(output)
# 
# Path: service/client.py
# class LocalClient(Client):
#     def __init__(self, port):
#         self._url = "http://127.0.0.1"
#         self._port = port


# Path: database/database_service.py
import logging
import os, sys, time
import ast
from database.memory_db import MemoryDB
from service.server import config
from service.server import Server
from service.components import Component
from service.client import LocalClient

from __future__ import absolute_import

logger = logging.getLogger(__name__)

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))



class DBQuery(Component):
    def __init__(self, db):
        self.db = db

    def process(self, json):
        output = {}
        try:
            output = self.db.query(json["product"], json["version"])
            logger.info("DB found: {} {}".format(json["product"], json["version"]))
        except Exception as e:
            logger.warn("DB miss: {} {}".format(json["product"], json["version"]))
        return output


class DBPrivileges(Component):