# Path: quads/model.py
# class Host(Document):
#     name = StringField(unique=True)
#     model = StringField()
#     default_cloud = ReferenceField(Cloud)
#     cloud = ReferenceField(Cloud)
#     host_type = StringField()
#     interfaces = ListField(EmbeddedDocumentField(Interface))
#     nullos = BooleanField(default=True)
#     build = BooleanField(default=False)
#     validated = BooleanField(default=False)
#     last_build = DateTimeField()
#     disks = ListField(EmbeddedDocumentField(Disk))
#     switch_config_applied = BooleanField(default=False)
#     broken = BooleanField(default=False)
#     retired = BooleanField(default=False)
#     meta = {"indexes": [{"fields": ["$name"]}], "strict": False}
# 
#     @staticmethod
#     def prep_data(data, fields=None):
#         if "cloud" in data:
#             _cloud_obj = Cloud.objects(name=data["cloud"]).first()
#             if _cloud_obj:
#                 data["cloud"] = _cloud_obj
#             else:
#                 return ["Cloud %s does not exist." % data["cloud"]], {}
#         if "default_cloud" in data:
#             _default_cloud_obj = Cloud.objects(name=data["default_cloud"]).first()
#             if _default_cloud_obj:
#                 data["default_cloud"] = _default_cloud_obj
#                 if "cloud" not in data:
#                     data["cloud"] = _default_cloud_obj
#             else:
#                 return ["Cloud %s does not exist." % data["default_cloud"]], {}
#         if not fields:
#             fields = ["name", "host_type"]
# 
#         result, data = param_check(data, fields)
# 
#         return result, data
# 
# class Schedule(Document):
#     cloud = ReferenceField(Cloud, required=True)
#     host = ReferenceField(Host, required=True)
#     start = DateTimeField()
#     end = DateTimeField()
#     build_start = DateTimeField()
#     build_end = DateTimeField()
#     index = IntField()
#     meta = {"strict": False}
# 
#     @staticmethod
#     def prep_data(data):
#         result, data = param_check(data, ["host"])
# 
#         return result, data
# 
#     @staticmethod
#     def get_next_sequence(name):
#         Counters.objects(_id=name).update_one(upsert=True, inc__seq=1)
#         return Counters.objects(_id=name).first()["seq"]
# 
#     def insert_schedule(self, cloud, host, start, end):
#         if host:
#             self.index = self.get_next_sequence(host)
#             self.host = Host.objects(name=host).first()
#         if cloud:
#             if type(cloud) == Cloud:
#                 self.cloud = cloud
#             else:
#                 self.cloud = Cloud.objects(name=cloud).first()
#         self.start = start
#         self.end = end
#         return self.save()
# 
#     @queryset_manager
#     def is_host_available(self, queryset, host, start, end, exclude=None):
#         _host = Host.objects(name=host).first()
#         if not _host:
#             return False
#         if _host.broken or _host.retired:
#             return False
#         _query = Q(host=_host)
#         if exclude:
#             _query = _query & Q(index__ne=exclude)
#         results = queryset.filter(_query)
#         for result in results:
#             if result["start"] <= start < result["end"]:
#                 return False
#             if result["start"] < end <= result["end"]:
#                 return False
#             if start < result["start"] and end > result["end"]:
#                 return False
#         return True
# 
#     @queryset_manager
#     def future_schedules(self, queryset, host=None, cloud=None):
#         now = datetime.datetime.now()
#         _query = Q(end__gte=now)
#         if host:
#             _query = _query & Q(host=host)
#         if cloud:
#             _query = _query & Q(cloud=cloud)
#         return queryset.filter(_query)
# 
#     @queryset_manager
#     def current_schedule(self, queryset, date=None, host=None, cloud=None):
#         if not date:
#             date = datetime.datetime.now()
#         _query = Q(start__lte=date) & Q(end__gte=date)
#         if host:
#             _query = _query & Q(host=host)
#         if cloud:
#             _query = _query & Q(cloud=cloud)
#         return queryset.no_cache().filter(_query)


from datetime import datetime, time
from mongoengine import Q
from app import app
from forms import ModelSearchForm
from flask import render_template, request, jsonify
from quads.model import Host, Schedule
@app.route("/", methods=["GET", "POST"])
def index():
    search = ModelSearchForm(request.form)
    if request.method == "POST":
        return search_results(search)

    return render_template("index.html", form=search, available_hosts=[])


@app.route("/results")
def search_results(search):
    available_hosts = available(search)

    return render_template("index.html", form=search, available_hosts=available_hosts)


@app.route("/available")
def available(search):
    models = search.data["model"]

    if models:
        query = None
        for model in models:
            if query:
                query = query | Q(model=model.upper())
            else:
                query = Q(model=model.upper())

        hosts = Host.objects.filter(query)
    else:

# Path: quads/model.py
# class Host(Document):
#     name = StringField(unique=True)
#     model = StringField()
#     default_cloud = ReferenceField(Cloud)
#     cloud = ReferenceField(Cloud)
#     host_type = StringField()
#     interfaces = ListField(EmbeddedDocumentField(Interface))
#     nullos = BooleanField(default=True)
#     build = BooleanField(default=False)
#     validated = BooleanField(default=False)
#     last_build = DateTimeField()
#     disks = ListField(EmbeddedDocumentField(Disk))
#     switch_config_applied = BooleanField(default=False)
#     broken = BooleanField(default=False)
#     retired = BooleanField(default=False)
#     meta = {"indexes": [{"fields": ["$name"]}], "strict": False}
# 
#     @staticmethod
#     def prep_data(data, fields=None):
#         if "cloud" in data:
#             _cloud_obj = Cloud.objects(name=data["cloud"]).first()
#             if _cloud_obj:
#                 data["cloud"] = _cloud_obj
#             else:
#                 return ["Cloud %s does not exist." % data["cloud"]], {}
#         if "default_cloud" in data:
#             _default_cloud_obj = Cloud.objects(name=data["default_cloud"]).first()
#             if _default_cloud_obj:
#                 data["default_cloud"] = _default_cloud_obj
#                 if "cloud" not in data:
#                     data["cloud"] = _default_cloud_obj
#             else:
#                 return ["Cloud %s does not exist." % data["default_cloud"]], {}
#         if not fields:
#             fields = ["name", "host_type"]
# 
#         result, data = param_check(data, fields)
# 
#         return result, data
# 
# class Schedule(Document):
#     cloud = ReferenceField(Cloud, required=True)
#     host = ReferenceField(Host, required=True)
#     start = DateTimeField()
#     end = DateTimeField()
#     build_start = DateTimeField()
#     build_end = DateTimeField()
#     index = IntField()
#     meta = {"strict": False}
# 
#     @staticmethod
#     def prep_data(data):
#         result, data = param_check(data, ["host"])
# 
#         return result, data
# 
#     @staticmethod
#     def get_next_sequence(name):
#         Counters.objects(_id=name).update_one(upsert=True, inc__seq=1)
#         return Counters.objects(_id=name).first()["seq"]
# 
#     def insert_schedule(self, cloud, host, start, end):
#         if host:
#             self.index = self.get_next_sequence(host)
#             self.host = Host.objects(name=host).first()
#         if cloud:
#             if type(cloud) == Cloud:
#                 self.cloud = cloud
#             else:
#                 self.cloud = Cloud.objects(name=cloud).first()
#         self.start = start
#         self.end = end
#         return self.save()
# 
#     @queryset_manager
#     def is_host_available(self, queryset, host, start, end, exclude=None):
#         _host = Host.objects(name=host).first()
#         if not _host:
#             return False
#         if _host.broken or _host.retired:
#             return False
#         _query = Q(host=_host)
#         if exclude:
#             _query = _query & Q(index__ne=exclude)
#         results = queryset.filter(_query)
#         for result in results:
#             if result["start"] <= start < result["end"]:
#                 return False
#             if result["start"] < end <= result["end"]:
#                 return False
#             if start < result["start"] and end > result["end"]:
#                 return False
#         return True
# 
#     @queryset_manager
#     def future_schedules(self, queryset, host=None, cloud=None):
#         now = datetime.datetime.now()
#         _query = Q(end__gte=now)
#         if host:
#             _query = _query & Q(host=host)
#         if cloud:
#             _query = _query & Q(cloud=cloud)
#         return queryset.filter(_query)
# 
#     @queryset_manager
#     def current_schedule(self, queryset, date=None, host=None, cloud=None):
#         if not date:
#             date = datetime.datetime.now()
#         _query = Q(start__lte=date) & Q(end__gte=date)
#         if host:
#             _query = _query & Q(host=host)
#         if cloud:
#             _query = _query & Q(cloud=cloud)
#         return queryset.no_cache().filter(_query)


# Path: web/main.py
from datetime import datetime, time
from mongoengine import Q
from app import app
from forms import ModelSearchForm
from flask import render_template, request, jsonify
from quads.model import Host, Schedule

@app.route("/", methods=["GET", "POST"])
def index():
    search = ModelSearchForm(request.form)
    if request.method == "POST":
        return search_results(search)

    return render_template("index.html", form=search, available_hosts=[])


@app.route("/results")
def search_results(search):
    available_hosts = available(search)

    return render_template("index.html", form=search, available_hosts=available_hosts)


@app.route("/available")
def available(search):
    models = search.data["model"]

    if models:
        query = None
        for model in models:
            if query:
                query = query | Q(model=model.upper())
            else:
                query = Q(model=model.upper())

        hosts = Host.objects.filter(query)
    else:

        hosts = Host.objects().all()