# Path: quads/helpers.py
# def date_span(start, end, delta=timedelta(days=1)):
#     current = start
#     while current < end:
#         yield current
#         current += delta
# 
# def first_day_month(date):
#     return date - timedelta(days=date.day - 1)
# 
# def last_day_month(date):
#     next_month = date.replace(day=28) + timedelta(days=4)
#     return next_month - timedelta(days=next_month.day)
# 
# def month_delta_past(date, months):
#     years = months // 12
#     year = date.year - years
#     month_delta = months % 12
#     if not month_delta:
#         return date.replace(year=year)
#     if month_delta > date.month:
#         year -= 1
#         month = 12 - month_delta
#         day = min(date.day, calendar.monthrange(year, month)[1])
#         return date.replace(year=year, month=month, day=day)
#     else:
#         month = date.month - month_delta
#         if month:
#             day = min(date.day, calendar.monthrange(year, month)[1])
#             return date.replace(year=year, month=month, day=day)
#         return date.replace(year=year)
# 
# def date_to_object_id(date):
#     """
#     Create a dummy ObjectId instance with a specific datetime.
# 
#     This method is useful for doing range queries by oid creation date.
# 
#     .. _warning:
#            It is not safe to insert a document containing an ObjectId
#            generated using this method. This method deliberately
#            eliminates the uniqueness guarantee that ObjectIds
#            generally provide. ObjectIds generated with this method
#            should be used exclusively in queries.
#     """
#     timestamp = calendar.timegm(date.timetuple())
#     oid = struct.pack(">I", int(timestamp)) + b"\x00\x00\x00\x00\x00\x00\x00\x00"
#     return ObjectId(oid)
# 
# Path: quads/model.py
# class Vlan(Document):
# class CloudHistory(Document):
# class Cloud(Document):
# class Notification(Document):
# class Disk(EmbeddedDocument):
# class Interface(EmbeddedDocument):
# class Host(Document):
# class Counters(Document):
# class Schedule(Document):
#     def prep_data(data):
#     def prep_data(data):
#     def prep_data(data, fields=None, mod=False):
#     def prep_data(data):
#     def prep_data(data, fields=None):
#     def prep_data(data, fields=None):
#     def prep_data(data):
#     def get_next_sequence(name):
#     def insert_schedule(self, cloud, host, start, end):
#     def is_host_available(self, queryset, host, start, end, exclude=None):
#     def future_schedules(self, queryset, host=None, cloud=None):
#     def current_schedule(self, queryset, date=None, host=None, cloud=None):


import logging
import sys
from quads.helpers import (
    date_span,
    first_day_month,
    last_day_month,
    month_delta_past,
    date_to_object_id,
)
from quads.model import Schedule, Host, CloudHistory, Cloud, Q
from datetime import datetime, timedelta

    schedules = Schedule.objects(build_start__ne=None, build_end__ne=None)
    total = timedelta()
    for schedule in schedules:
        total += schedule.build_end - schedule.build_start
    if schedules:
        average_build = total / len(schedules)
        _logger.info(f"Average build delta: {average_build}")

    hosts_summary = {}
    for host in hosts:
        host_type = host.name.split(".")[0].split("-")[-1]
        if not hosts_summary.get(host_type):
            hosts_summary[host_type] = []
        hosts_summary[host_type].append(host)

    headers = ["Server Type", "Total", "Free", "Scheduled", "2 weeks", "4 weeks"]
    _logger.info(
        f"{headers[0]:<12}| "
        f"{headers[1]:>5}| "
        f"{headers[2]:>5}| "
        f"{headers[3]:>9}| "
        f"{headers[4]:>7}| "
        f"{headers[5]:>7}"
    )
    for host_type, _hosts in hosts_summary.items():
        scheduled_count = 0
        two_weeks_availability_count = 0
        four_weeks_availability_count = 0
        for host in _hosts:

# Path: quads/helpers.py
# def date_span(start, end, delta=timedelta(days=1)):
#     current = start
#     while current < end:
#         yield current
#         current += delta
# 
# def first_day_month(date):
#     return date - timedelta(days=date.day - 1)
# 
# def last_day_month(date):
#     next_month = date.replace(day=28) + timedelta(days=4)
#     return next_month - timedelta(days=next_month.day)
# 
# def month_delta_past(date, months):
#     years = months // 12
#     year = date.year - years
#     month_delta = months % 12
#     if not month_delta:
#         return date.replace(year=year)
#     if month_delta > date.month:
#         year -= 1
#         month = 12 - month_delta
#         day = min(date.day, calendar.monthrange(year, month)[1])
#         return date.replace(year=year, month=month, day=day)
#     else:
#         month = date.month - month_delta
#         if month:
#             day = min(date.day, calendar.monthrange(year, month)[1])
#             return date.replace(year=year, month=month, day=day)
#         return date.replace(year=year)
# 
# def date_to_object_id(date):
#     """
#     Create a dummy ObjectId instance with a specific datetime.
# 
#     This method is useful for doing range queries by oid creation date.
# 
#     .. _warning:
#            It is not safe to insert a document containing an ObjectId
#            generated using this method. This method deliberately
#            eliminates the uniqueness guarantee that ObjectIds
#            generally provide. ObjectIds generated with this method
#            should be used exclusively in queries.
#     """
#     timestamp = calendar.timegm(date.timetuple())
#     oid = struct.pack(">I", int(timestamp)) + b"\x00\x00\x00\x00\x00\x00\x00\x00"
#     return ObjectId(oid)
# 
# Path: quads/model.py
# class Vlan(Document):
# class CloudHistory(Document):
# class Cloud(Document):
# class Notification(Document):
# class Disk(EmbeddedDocument):
# class Interface(EmbeddedDocument):
# class Host(Document):
# class Counters(Document):
# class Schedule(Document):
#     def prep_data(data):
#     def prep_data(data):
#     def prep_data(data, fields=None, mod=False):
#     def prep_data(data):
#     def prep_data(data, fields=None):
#     def prep_data(data, fields=None):
#     def prep_data(data):
#     def get_next_sequence(name):
#     def insert_schedule(self, cloud, host, start, end):
#     def is_host_available(self, queryset, host, start, end, exclude=None):
#     def future_schedules(self, queryset, host=None, cloud=None):
#     def current_schedule(self, queryset, date=None, host=None, cloud=None):


# Path: quads/tools/reports.py
import logging
import sys
from quads.helpers import (
    date_span,
    first_day_month,
    last_day_month,
    month_delta_past,
    date_to_object_id,
)
from quads.model import Schedule, Host, CloudHistory, Cloud, Q
from datetime import datetime, timedelta


    schedules = Schedule.objects(build_start__ne=None, build_end__ne=None)
    total = timedelta()
    for schedule in schedules:
        total += schedule.build_end - schedule.build_start
    if schedules:
        average_build = total / len(schedules)
        _logger.info(f"Average build delta: {average_build}")

    hosts_summary = {}
    for host in hosts:
        host_type = host.name.split(".")[0].split("-")[-1]
        if not hosts_summary.get(host_type):
            hosts_summary[host_type] = []
        hosts_summary[host_type].append(host)

    headers = ["Server Type", "Total", "Free", "Scheduled", "2 weeks", "4 weeks"]
    _logger.info(
        f"{headers[0]:<12}| "
        f"{headers[1]:>5}| "
        f"{headers[2]:>5}| "
        f"{headers[3]:>9}| "
        f"{headers[4]:>7}| "
        f"{headers[5]:>7}"
    )
    for host_type, _hosts in hosts_summary.items():
        scheduled_count = 0
        two_weeks_availability_count = 0
        four_weeks_availability_count = 0
        for host in _hosts:

            schedule = Schedule.current_schedule(host=host)