<?php

class DbUtils {

    // summary database table name
    private const TABLE_SUMMARY = "assignsubmission_dta_summary";
    // result database table name
    private const TABLE_RESULT = "assignsubmission_dta_result";

    /**
     * get's summary with all corresponding result entries
     *
     * @param int $assignmentId assignment id to search for
     * @param int $submissionId submission id to search for
     * @return DttResultSummary representing given submission
     */
    public static function getResultSummaryFromDatabase(
        int $assignmentId,
        int $submissionId
    ): DtaResultSummary {
        global $DB;

        // fetch data from database
        $summaryDbRecord = $DB->get_record(self::TABLE_SUMMARY, array(
            "assignment_id" => $assignmentId,
            "submission_id" => $submissionId
        ));

        $resultsDbArray = $DB->get_records(self::TABLE_RESULT, array(
            "assignment_id" => $assignmentId,
            "submission_id" => $submissionId
        ));

        // create summary instance
        $summary = new DtaResultSummary();
        $summary->timestamp = $summaryDbRecord->timestamp;
        $summary->globalStacktrace = $summaryDbRecord->global_stacktrace;
		$summary->successfulTestCompetencyProfile = $summaryDbRecord->successful_competencies;
		$summary->overallTestCompetencyProfile = $summaryDbRecord->tested_competencies;
        $summary->results = array();

        // create result instances and add to array of summary instance
        foreach($resultsDbArray as $rr) {
            $result = new DtaResult();
			$result->packageName = $rr->package_name;
            $result->className = $rr->class_name;
            $result->name = $rr->name;
            $result->state = $rr->state;
            $result->failureType = $rr->failure_type;
            $result->failureReason = $rr->failure_reason;
            $result->stacktrace = $rr->stacktrace;
            $result->columnNumber = $rr->column_number;
            $result->lineNumber = $rr->line_number;
            $result->position = $rr->position;

            $summary->results[] = $result;
        }

        return $summary;
    }

    /**
     * save given result summary and single results to database
     * under given assignment and submission id
     *
     * @param int assignmentId assigment this is submission is linked to
     * @param int submissionId submission of this result
     * @param DttResultSummary instance to persist
     */
    public static function storeResultSummaryToDatabase(
        int $assignmentId,
        int $submissionId,
        DtaResultSummary $summary
    ): void {
        global $DB;

        // prepare new database entries
        $summaryRecord = new stdClass();
        $summaryRecord->assignment_id = $assignmentId;
        $summaryRecord->submission_id = $submissionId;
		$summaryRecord->successful_competencies = $summary->successfulTestCompetencyProfile;
		$summaryRecord->tested_competencies = $summary->overallTestCompetencyProfile;
        $summaryRecord->timestamp = $summary->timestamp;
        $summaryRecord->global_stacktrace = $summary->globalStacktrace;

        // prepare results to persist to array
        $resultRecordArray = array();
        foreach($summary->results as $r) {
            $record = new stdClass();
            $record->assignment_id = $assignmentId;
            $record->submission_id = $submissionId;
			$record->package_name = $r->packageName;
            $record->class_name = $r->className;
            $record->name = $r->name;
            $record->state = $r->state;
            $record->failure_type = $r->failureType;
            $record->failure_reason = $r->failureReason;
            $record->stacktrace = $r->stacktrace;
            $record->column_number = $r->columnNumber;
            $record->line_number = $r->lineNumber;
            $record->position = $r->position;
            $resultRecordArray[] = $record;
        }

        // if results exist yet, delete old values beforehand
        $submission = $DB->get_record(self::TABLE_SUMMARY, array(
            'assignment_id' => $assignmentId,
            'submission_id' => $submissionId
        ));

        if ($submission) {
            $DB->delete_records(self::TABLE_RESULT, array(
                'assignment_id' => $assignmentId,
                'submission_id' => $submissionId
            ));

            $DB->delete_records(self::TABLE_SUMMARY, array(
                'assignment_id' => $assignmentId,
                'submission_id' => $submissionId
            ));
        }

        // create summary and single result entries
        $DB->insert_record(self::TABLE_SUMMARY, $summaryRecord);
        foreach($resultRecordArray as $rr) {
            $DB->insert_record(self::TABLE_RESULT, $rr);
        }
    }

    /**
     * cleans up database if plugin is uninstalled
     */
    public static function uninstallPluginCleanUp(): void {
        global $DB;

        $DB->delete_records(self::TABLE_RESULT, null);
        $DB->delete_records(self::TABLE_SUMMARY, null);
    }

}