# Path: mothership/forms.py
# class CampaignForm(Form):
# class MakeTestsForm(Form):
# 	def validate(self):
# 	def validate(self):
# 
# Path: mothership/models.py
# def init_db():
# 	def process_bind_param(self, value, dialect):
# 	def process_result_value(self, value, dialect):
# 	def get(cls, **kwargs):
# 	def all(cls, **kwargs):
# 	def create(cls, **kwargs):
# 	def put(self):
# 	def delete(self):
# 	def commit():
# 	def update(self, **kwargs):
# 	def update_all(cls, **kwargs):
# 	def to_dict(self):
# 	def children(self):
# 	def __init__(self, name):
# 	def started(self):
# 	def active_fuzzers(self):
# 	def master_fuzzer(self):
# 	def num_executions(self):
# 	def num_crashes(self):
# 	def bitmap_cvg(self):
# 	def name(self):
# 	def campaign(self):
# 	def started(self):
# 	def running(self):
# class JsonType(types.TypeDecorator):
# class Model:
# class Campaign(Model, db.Model):
# class FuzzerInstance(Model, db.Model):
# class FuzzerSnapshot(Model, db.Model):
# class Crash(Model, db.Model):
# 
# Path: mothership/utils.py
# def format_timedelta_secs(secs, time_format='{days} days {hours} hours {minutes} minutes'):
# 	return format_timedelta(datetime.timedelta(seconds=secs), time_format=time_format)
# 
# def pretty_size_dec(value):
# 	return pretty_size(value, b=1000, u = '', pre = ['', 'Thousand', 'Million', 'Billion'])
# 
# def format_ago(current_time, ago):
# 	return (format_timedelta_secs(current_time - ago) + ' ago') if ago else 'none so far',


import shutil
import subprocess
import time
import os
import sqlalchemy
from flask import Blueprint, render_template, render_template_string, flash, redirect, request, url_for, jsonify, current_app
from datetime import datetime
from sqlalchemy import case
from werkzeug.utils import secure_filename
from mothership import forms, models
from mothership.utils import format_timedelta_secs, pretty_size_dec, format_ago
	])

def count_crashes(crashes, **kwargs):
	return sum(1 if all(hasattr(crash, k) and getattr(crash, k) == v for k, v in kwargs.items()) else 0 for crash in crashes)

@campaigns.route('/campaigns/stats/<int:campaign_id>')
def stats(campaign_id):
	campaign_model = models.Campaign.get(id=campaign_id)
	current_time = int(time.time())
	total_executions, combined_run, last_path, last_crash, last_update = 0, 0, 0, 0, 0
	for instance in campaign_model.fuzzers:
		if instance.started:
			total_executions += instance.execs_done
			combined_run += instance.last_update - instance.start_time
			last_path = max(last_path, instance.last_path)
			last_crash = max(last_crash, instance.last_crash)
			last_update = max(last_update, instance.last_update)
	crashes = list(models.Crash.query.filter_by(campaign_id=campaign_id, analyzed=True, crash_in_debugger=True).group_by(models.Crash.backtrace))
	cvg = campaign_model.bitmap_cvg

	return jsonify(
		now=current_time,

		total_executions=total_executions,
		total_executions_str=pretty_size_dec(total_executions),

		combined_run=total_executions,
		combined_run_str=format_timedelta_secs(combined_run),

		last_instance=last_update,

# Path: mothership/forms.py
# class CampaignForm(Form):
# class MakeTestsForm(Form):
# 	def validate(self):
# 	def validate(self):
# 
# Path: mothership/models.py
# def init_db():
# 	def process_bind_param(self, value, dialect):
# 	def process_result_value(self, value, dialect):
# 	def get(cls, **kwargs):
# 	def all(cls, **kwargs):
# 	def create(cls, **kwargs):
# 	def put(self):
# 	def delete(self):
# 	def commit():
# 	def update(self, **kwargs):
# 	def update_all(cls, **kwargs):
# 	def to_dict(self):
# 	def children(self):
# 	def __init__(self, name):
# 	def started(self):
# 	def active_fuzzers(self):
# 	def master_fuzzer(self):
# 	def num_executions(self):
# 	def num_crashes(self):
# 	def bitmap_cvg(self):
# 	def name(self):
# 	def campaign(self):
# 	def started(self):
# 	def running(self):
# class JsonType(types.TypeDecorator):
# class Model:
# class Campaign(Model, db.Model):
# class FuzzerInstance(Model, db.Model):
# class FuzzerSnapshot(Model, db.Model):
# class Crash(Model, db.Model):
# 
# Path: mothership/utils.py
# def format_timedelta_secs(secs, time_format='{days} days {hours} hours {minutes} minutes'):
# 	return format_timedelta(datetime.timedelta(seconds=secs), time_format=time_format)
# 
# def pretty_size_dec(value):
# 	return pretty_size(value, b=1000, u = '', pre = ['', 'Thousand', 'Million', 'Billion'])
# 
# def format_ago(current_time, ago):
# 	return (format_timedelta_secs(current_time - ago) + ' ago') if ago else 'none so far',


# Path: mothership/controllers/campaigns.py
import shutil
import subprocess
import time
import os
import sqlalchemy
from flask import Blueprint, render_template, render_template_string, flash, redirect, request, url_for, jsonify, current_app
from datetime import datetime
from sqlalchemy import case
from werkzeug.utils import secure_filename
from mothership import forms, models
from mothership.utils import format_timedelta_secs, pretty_size_dec, format_ago

	])

def count_crashes(crashes, **kwargs):
	return sum(1 if all(hasattr(crash, k) and getattr(crash, k) == v for k, v in kwargs.items()) else 0 for crash in crashes)

@campaigns.route('/campaigns/stats/<int:campaign_id>')
def stats(campaign_id):
	campaign_model = models.Campaign.get(id=campaign_id)
	current_time = int(time.time())
	total_executions, combined_run, last_path, last_crash, last_update = 0, 0, 0, 0, 0
	for instance in campaign_model.fuzzers:
		if instance.started:
			total_executions += instance.execs_done
			combined_run += instance.last_update - instance.start_time
			last_path = max(last_path, instance.last_path)
			last_crash = max(last_crash, instance.last_crash)
			last_update = max(last_update, instance.last_update)
	crashes = list(models.Crash.query.filter_by(campaign_id=campaign_id, analyzed=True, crash_in_debugger=True).group_by(models.Crash.backtrace))
	cvg = campaign_model.bitmap_cvg

	return jsonify(
		now=current_time,

		total_executions=total_executions,
		total_executions_str=pretty_size_dec(total_executions),

		combined_run=total_executions,
		combined_run_str=format_timedelta_secs(combined_run),

		last_instance=last_update,

		last_instance_str=format_ago(current_time, last_update),