<commit_before>package org.slc.sli.test.edfi.entities.meta.relations;

import java.util.HashMap;
import java.util.Map;

import org.slc.sli.test.edfi.entities.meta.CohortMeta;
import org.slc.sli.test.edfi.entities.meta.CourseMeta;
import org.slc.sli.test.edfi.entities.meta.LeaMeta;
import org.slc.sli.test.edfi.entities.meta.ProgramMeta;
import org.slc.sli.test.edfi.entities.meta.SchoolMeta;
import org.slc.sli.test.edfi.entities.meta.SeaMeta;
import org.slc.sli.test.edfi.entities.meta.SectionMeta;
import org.slc.sli.test.edfi.entities.meta.SessionMeta;
import org.slc.sli.test.edfi.entities.meta.StaffMeta;
import org.slc.sli.test.edfi.entities.meta.StudentAssessmentMeta;
import org.slc.sli.test.edfi.entities.meta.StudentMeta;
import org.slc.sli.test.edfi.entities.meta.TeacherMeta;

public final class MetaRelations {

    // knobs to control number of entities to create
    public static final int TOTAL_SEAS = 1;
    public static final int LEAS_PER_SEA = 1;
    public static final int STAFF_PER_SEA = 3;
    public static final int SCHOOLS_PER_LEA = 2;
    public static final int COURSES_PER_SCHOOL = 2;
    public static final int SESSIONS_PER_SCHOOL = 1;
    public static final int SECTIONS_PER_COURSE_SESSION = 1;
    public static final int TEACHERS_PER_SCHOOL = 1;
    public static final int STUDENTS_PER_SCHOOL = 25;
    public static final int PROGRAMS_PER_SCHOOL = 2;
    public static final int FREE_STANDING_COHORT_PER_SCHOOL = 2;
    public static final int FREE_STANDING_COHORT_SIZE = 4;
    public static final int INV_PROB_SECTION_HAS_PROGRAM = 10;
    public static final int ASSESSMENTS_PER_STUDENT = 10;

    // publicly accessible structures for the "meta-skeleton" entities populated by "buildFromSea()"
    public static final Map<String, SeaMeta> SEA_MAP = new HashMap<String, SeaMeta>();
    public static final Map<String, LeaMeta> LEA_MAP = new HashMap<String, LeaMeta>();
    public static final Map<String, SchoolMeta> SCHOOL_MAP = new HashMap<String, SchoolMeta>();
    public static final Map<String, CourseMeta> COURSE_MAP = new HashMap<String, CourseMeta>();

    public static final Map<String, SessionMeta> SESSION_MAP = new HashMap<String, SessionMeta>();

    public static final Map<String, SectionMeta> SECTION_MAP = new HashMap<String, SectionMeta>();

    public static final Map<String, StaffMeta> STAFF_MAP = new HashMap<String, StaffMeta>();
    public static final Map<String, TeacherMeta> TEACHER_MAP = new HashMap<String, TeacherMeta>();

    public static final Map<String, StudentMeta> STUDENT_MAP = new HashMap<String, StudentMeta>();

    public static final Map<String, ProgramMeta> PROGRAM_MAP = new HashMap<String, ProgramMeta>();

    public static final Map<String, CohortMeta> COHORT_MAP = new HashMap<String, CohortMeta>();

    public static final Map<String, StudentAssessmentMeta> STUDENT_ASSES_MAP = new HashMap<String, StudentAssessmentMeta>();

    /**
     * Construct the meta relationships necessary for XML interchanges
     */
    public static void construct() {

        long startTime = System.currentTimeMillis();

        buildSeas();

        AssessmentMetaRelations.buildStandaloneAssessments();

        assignAssessmentsToStudents();

        System.out.println("Time taken to build entity relationships: " + (System.currentTimeMillis() - startTime));

    }

    /**
     * Looping over all SEAs, build LEAs for each SEA
     */
    private static void buildSeas() {

        for (int idNum = 0; idNum < TOTAL_SEAS; idNum++) {

            SeaMeta seaMeta = new SeaMeta("sea" + idNum);

            SEA_MAP.put(seaMeta.id, seaMeta);

            buildAndRelateEntitiesWithSea(seaMeta);
        }
    }

    private static void buildAndRelateEntitiesWithSea(SeaMeta seaMeta) {

        Map<String, StaffMeta> staffForSea = buildStaffForSea(seaMeta);

        buildLeasForSea(seaMeta, staffForSea);
    }

    /**
     * Create staff relations for each sea
     */
    private static Map<String, StaffMeta> buildStaffForSea(SeaMeta seaMeta) {

        Map<String, StaffMeta> staffInSeaMap = new HashMap<String, StaffMeta>(STAFF_PER_SEA);
        for (int idNum = 0; idNum < STAFF_PER_SEA; idNum++) {

            StaffMeta staffMeta = StaffMeta.createWithChainedId("staff" + idNum, seaMeta);

            STAFF_MAP.put(staffMeta.id, staffMeta);
            staffInSeaMap.put(staffMeta.id, staffMeta);
        }
        return staffInSeaMap;
    }

    /**
     * Looping over all LEAs, build Schools for each LEA
     *
     * @param seaMeta
     */
    private static void buildLeasForSea(SeaMeta seaMeta, Map<String, StaffMeta> staffForSea) {

        for (int idNum = 0; idNum < LEAS_PER_SEA; idNum++) {

            LeaMeta leaMeta = new LeaMeta("lea" + idNum, seaMeta);

            LEA_MAP.put(leaMeta.id, leaMeta);

            buildSchoolsForLea(leaMeta, staffForSea);
        }
    }

    /**
     * For each School, generate:
     * - teachers
     * - courses
     * - sessions
     * - sections
     * And correlate sections with teachers.
     *
     * @param leaMeta
     */
    private static void buildSchoolsForLea(LeaMeta leaMeta, Map<String, StaffMeta> staffForSea) {

        for (int idNum = 0; idNum < SCHOOLS_PER_LEA; idNum++) {

            SchoolMeta schoolMeta = new SchoolMeta("sch" + idNum, leaMeta);

            SCHOOL_MAP.put(schoolMeta.id, schoolMeta);

            buildAndRelateEntitiesWithSchool(schoolMeta, staffForSea);
        }
    }

    private static void buildAndRelateEntitiesWithSchool(SchoolMeta schoolMeta, Map<String, StaffMeta> staffForSea) {

        Map<String, TeacherMeta> teachersForSchool = buildTeachersForSchool(schoolMeta);

        Map<String, StudentMeta> studentsForSchool = buildStudentsForSchool(schoolMeta);

        Map<String, CourseMeta> coursesForSchool = buildCoursesForSchool(schoolMeta);

        Map<String, SessionMeta> sessionsForSchool = buildSessionsForSchool(schoolMeta);

        Map<String, ProgramMeta> programForSchool = buildProgramsForSchool(schoolMeta);

        Map<String, SectionMeta> sectionsForSchool = buildSectionsForSchool(schoolMeta, coursesForSchool,
                sessionsForSchool, programForSchool);

        Map<String, CohortMeta> freeStandingCohortsForSchool = buildFreeStandingCohortsForSchool(schoolMeta);

        addSectionsToTeachers(sectionsForSchool, teachersForSchool);

        addStudentsToSections(sectionsForSchool, studentsForSchool);

        addStudentsToPrograms(sectionsForSchool, studentsForSchool, programForSchool);

        addStaffToPrograms(programForSchool, staffForSea);

        addStaffStudentToFreeStandingCohorts(freeStandingCohortsForSchool, studentsForSchool, staffForSea);

    }

    /**
     * Generate the teachers for this school.
     * teachersInSchoolMap is used later in this class.
     * TEACHER_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @return
     */
    private static Map<String, TeacherMeta> buildTeachersForSchool(SchoolMeta schoolMeta) {

        Map<String, TeacherMeta> teachersInSchoolMap = new HashMap<String, TeacherMeta>(TEACHERS_PER_SCHOOL);
        for (int idNum = 0; idNum < TEACHERS_PER_SCHOOL; idNum++) {

            TeacherMeta teacherMeta;
            if (idNum == 0) {
                // hardcode first teacher as he is set up in ny idp
                teacherMeta = TeacherMeta.create("wadama", schoolMeta);
            } else {
                teacherMeta = TeacherMeta.createWithChainedId("teacher" + idNum, schoolMeta);
            }

            // it's useful to return the objects created JUST for this school
            // add to both maps here to avoid loop in map.putAll if we merged maps later
            teachersInSchoolMap.put(teacherMeta.id, teacherMeta);
            TEACHER_MAP.put(teacherMeta.id, teacherMeta);
        }

        return teachersInSchoolMap;
    }

    /**
     * Generate the students for this school.
     * studentsInSchoolMap is used later in this class.
     * STUDENT_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @return
     */
    private static Map<String, StudentMeta> buildStudentsForSchool(SchoolMeta schoolMeta) {

        Map<String, StudentMeta> studentsInSchoolMap = new HashMap<String, StudentMeta>(STUDENTS_PER_SCHOOL);
        for (int idNum = 0; idNum < STUDENTS_PER_SCHOOL; idNum++) {

            StudentMeta studentMeta = new StudentMeta("student" + idNum, schoolMeta);

            // it's useful to return the objects created JUST for this school
            // add to both maps here to avoid loop in map.putAll if we merged maps later
            studentsInSchoolMap.put(studentMeta.id, studentMeta);
            STUDENT_MAP.put(studentMeta.id, studentMeta);
        }

        return studentsInSchoolMap;
    }

    /**
     * Generate the courses for the school.
     * coursesForSchool is used later in this class.
     * COURSE_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @return
     */
    private static Map<String, CourseMeta> buildCoursesForSchool(SchoolMeta schoolMeta) {

        Map<String, CourseMeta> coursesForSchool = new HashMap<String, CourseMeta>(COURSES_PER_SCHOOL);

        for (int idNum = 0; idNum < COURSES_PER_SCHOOL; idNum++) {

            CourseMeta courseMeta = new CourseMeta("course" + idNum, schoolMeta);

            // it's useful to return the objects created JUST for this school
            // add to both maps here to avoid loop in map.putAll if we merged maps later
            coursesForSchool.put(courseMeta.id, courseMeta);
            COURSE_MAP.put(courseMeta.id, courseMeta);
        }

        return coursesForSchool;
    }

    /**
     * Generate the sessions for the school.
     * sessionsForSchool is used later in this class.
     * SESSION_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @return
     */
    private static Map<String, SessionMeta> buildSessionsForSchool(SchoolMeta schoolMeta) {

        Map<String, SessionMeta> sessionsForSchool = new HashMap<String, SessionMeta>(SESSIONS_PER_SCHOOL);

        for (int idNum = 0; idNum < SESSIONS_PER_SCHOOL; idNum++) {

            SessionMeta sessionMeta = new SessionMeta("session" + idNum, schoolMeta);

            // it's useful to return the objects created JUST for this school
            // add to both maps here to avoid loop in map.putAll if we merged maps later
            sessionsForSchool.put(sessionMeta.id, sessionMeta);
            SESSION_MAP.put(sessionMeta.id, sessionMeta);
        }

        return sessionsForSchool;
    }

    /**
     * Generate the sections for this school.
     * sectionMapForSchool is used later in this class.
     * SECTION_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @param coursesForSchool
     * @param sessionsForSchool
     * @param programsForSchool
     * @return
     */
    private static Map<String, SectionMeta> buildSectionsForSchool(SchoolMeta schoolMeta,
            Map<String, CourseMeta> coursesForSchool, Map<String, SessionMeta> sessionsForSchool,
            Map<String, ProgramMeta> programsForSchool) {

        Map<String, SectionMeta> sectionMapForSchool = new HashMap<String, SectionMeta>();

        Object[] programMetas = programsForSchool.values().toArray();
        int programCounter = 0;

        for (SessionMeta sessionMeta : sessionsForSchool.values()) {

            for (CourseMeta courseMeta : coursesForSchool.values()) {

                for (int idNum = 0; idNum < SECTIONS_PER_COURSE_SESSION; idNum++) {

                    // program reference in section is optional; will create one program reference
                    // for every inverse-probability-section-has-program section
                    ProgramMeta programMeta = null;
                    if (sectionMapForSchool.size() % INV_PROB_SECTION_HAS_PROGRAM == 0) {
                        programMeta = (ProgramMeta) programMetas[programCounter];
                        programCounter = (programCounter + 1) % programMetas.length;
                    }

                    SectionMeta sectionMeta = new SectionMeta("section" + idNum, schoolMeta, courseMeta, sessionMeta,
                            programMeta);<commit_msg>code cleanup. use TreeMaps so the collections return in order<commit_after>package org.slc.sli.test.edfi.entities.meta.relations;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import org.slc.sli.test.edfi.entities.meta.CohortMeta;
import org.slc.sli.test.edfi.entities.meta.CourseMeta;
import org.slc.sli.test.edfi.entities.meta.LeaMeta;
import org.slc.sli.test.edfi.entities.meta.ProgramMeta;
import org.slc.sli.test.edfi.entities.meta.SchoolMeta;
import org.slc.sli.test.edfi.entities.meta.SeaMeta;
import org.slc.sli.test.edfi.entities.meta.SectionMeta;
import org.slc.sli.test.edfi.entities.meta.SessionMeta;
import org.slc.sli.test.edfi.entities.meta.StaffMeta;
import org.slc.sli.test.edfi.entities.meta.StudentAssessmentMeta;
import org.slc.sli.test.edfi.entities.meta.StudentMeta;
import org.slc.sli.test.edfi.entities.meta.TeacherMeta;

public final class MetaRelations {

    // knobs to control number of entities to create
    public static final int TOTAL_SEAS = 1;
    public static final int LEAS_PER_SEA = 2;
    public static final int STAFF_PER_SEA = 0;
    public static final int SCHOOLS_PER_LEA = 2;
    public static final int COURSES_PER_SCHOOL = 2;
    public static final int SESSIONS_PER_SCHOOL = 1;
    public static final int SECTIONS_PER_COURSE_SESSION = 1;
    public static final int TEACHERS_PER_SCHOOL = 10;
    public static final int STUDENTS_PER_SCHOOL = 10;
    public static final int PROGRAMS_PER_SCHOOL = 0;
    public static final int FREE_STANDING_COHORT_PER_SCHOOL = 0;
    public static final int FREE_STANDING_COHORT_SIZE = 0;
    public static final int INV_PROB_SECTION_HAS_PROGRAM = 10;
    public static final int ASSESSMENTS_PER_STUDENT = 5;
    public static final int ATTENDANCE_PER_STUDENT_SECTION = 1;

    // publicly accessible structures for the "meta-skeleton" entities populated by "buildFromSea()"
    // TODO: do we need maps? maybe just use Collections?
    public static final Map<String, SeaMeta> SEA_MAP = new TreeMap<String, SeaMeta>();
    public static final Map<String, LeaMeta> LEA_MAP = new TreeMap<String, LeaMeta>();
    public static final Map<String, SchoolMeta> SCHOOL_MAP = new TreeMap<String, SchoolMeta>();
    public static final Map<String, CourseMeta> COURSE_MAP = new TreeMap<String, CourseMeta>();
    public static final Map<String, SessionMeta> SESSION_MAP = new TreeMap<String, SessionMeta>();
    public static final Map<String, SectionMeta> SECTION_MAP = new TreeMap<String, SectionMeta>();
    public static final Map<String, StaffMeta> STAFF_MAP = new TreeMap<String, StaffMeta>();
    public static final Map<String, TeacherMeta> TEACHER_MAP = new TreeMap<String, TeacherMeta>();
    public static final Map<String, StudentMeta> STUDENT_MAP = new TreeMap<String, StudentMeta>();
    public static final Map<String, ProgramMeta> PROGRAM_MAP = new TreeMap<String, ProgramMeta>();
    public static final Map<String, CohortMeta> COHORT_MAP = new TreeMap<String, CohortMeta>();
    public static final Map<String, StudentAssessmentMeta> STUDENT_ASSES_MAP = new TreeMap<String, StudentAssessmentMeta>();

    public static final String SEA_PREFIX = "caprica";
    public static final String FIRST_TEACHER_ID = "lroslin";

    /**
     * Construct the meta relationships necessary for XML interchanges
     */
    public static void construct() {

        long startTime = System.currentTimeMillis();

        buildSeas();

        AssessmentMetaRelations.buildStandaloneAssessments();

        assignAssessmentsToStudents();

        System.out.println("Time taken to build entity relationships: " + (System.currentTimeMillis() - startTime));

    }

    /**
     * Looping over all SEAs, build LEAs for each SEA
     */
    private static void buildSeas() {

        for (int idNum = 0; idNum < TOTAL_SEAS; idNum++) {

            SeaMeta seaMeta = new SeaMeta(SEA_PREFIX + idNum);

            SEA_MAP.put(seaMeta.id, seaMeta);

            buildAndRelateEntitiesWithSea(seaMeta);
        }
    }

    private static void buildAndRelateEntitiesWithSea(SeaMeta seaMeta) {

        Map<String, StaffMeta> staffForSea = buildStaffForSea(seaMeta);

        buildLeasForSea(seaMeta, staffForSea);
    }

    /**
     * Create staff relations for each sea
     */
    private static Map<String, StaffMeta> buildStaffForSea(SeaMeta seaMeta) {

        Map<String, StaffMeta> staffInSeaMap = new HashMap<String, StaffMeta>(STAFF_PER_SEA);
        for (int idNum = 0; idNum < STAFF_PER_SEA; idNum++) {

            StaffMeta staffMeta = StaffMeta.createWithChainedId("staff" + idNum, seaMeta);

            STAFF_MAP.put(staffMeta.id, staffMeta);
            staffInSeaMap.put(staffMeta.id, staffMeta);
        }
        return staffInSeaMap;
    }

    /**
     * Looping over all LEAs, build Schools for each LEA
     *
     * @param seaMeta
     */
    private static void buildLeasForSea(SeaMeta seaMeta, Map<String, StaffMeta> staffForSea) {

        for (int idNum = 0; idNum < LEAS_PER_SEA; idNum++) {

            LeaMeta leaMeta = new LeaMeta("lea" + idNum, seaMeta);

            LEA_MAP.put(leaMeta.id, leaMeta);

            buildSchoolsForLea(leaMeta, staffForSea);
        }
    }

    /**
     * For each School, generate:
     * - teachers
     * - courses
     * - sessions
     * - sections
     * And correlate sections with teachers.
     *
     * @param leaMeta
     */
    private static void buildSchoolsForLea(LeaMeta leaMeta, Map<String, StaffMeta> staffForSea) {

        for (int idNum = 0; idNum < SCHOOLS_PER_LEA; idNum++) {

            SchoolMeta schoolMeta = new SchoolMeta("sch" + idNum, leaMeta);

            SCHOOL_MAP.put(schoolMeta.id, schoolMeta);

            buildAndRelateEntitiesWithSchool(schoolMeta, staffForSea);
        }
    }

    private static void buildAndRelateEntitiesWithSchool(SchoolMeta schoolMeta, Map<String, StaffMeta> staffForSea) {

        Map<String, TeacherMeta> teachersForSchool = buildTeachersForSchool(schoolMeta);

        Map<String, StudentMeta> studentsForSchool = buildStudentsForSchool(schoolMeta);

        Map<String, CourseMeta> coursesForSchool = buildCoursesForSchool(schoolMeta);

        Map<String, SessionMeta> sessionsForSchool = buildSessionsForSchool(schoolMeta);

        Map<String, ProgramMeta> programForSchool = buildProgramsForSchool(schoolMeta);

        Map<String, SectionMeta> sectionsForSchool = buildSectionsForSchool(schoolMeta, coursesForSchool,
                sessionsForSchool, programForSchool);

        Map<String, CohortMeta> freeStandingCohortsForSchool = buildFreeStandingCohortsForSchool(schoolMeta);

        addSectionsToTeachers(sectionsForSchool, teachersForSchool);

        addStudentsToSections(sectionsForSchool, studentsForSchool);

        addStudentsToPrograms(sectionsForSchool, studentsForSchool, programForSchool);

        addStaffToPrograms(programForSchool, staffForSea);

        addStaffStudentToFreeStandingCohorts(freeStandingCohortsForSchool, studentsForSchool, staffForSea);

    }

    // hacky way to generate 1 special teacher
    private static boolean createdSpecialTeacher = false;

    /**
     * Generate the teachers for this school.
     * teachersInSchoolMap is used later in this class.
     * TEACHER_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @return
     */
    private static Map<String, TeacherMeta> buildTeachersForSchool(SchoolMeta schoolMeta) {

        Map<String, TeacherMeta> teachersInSchoolMap = new HashMap<String, TeacherMeta>(TEACHERS_PER_SCHOOL);
        for (int idNum = 0; idNum < TEACHERS_PER_SCHOOL; idNum++) {

            TeacherMeta teacherMeta;
            if (!createdSpecialTeacher) {
                // hardcode first teacher so we can log in as established user
                teacherMeta = TeacherMeta.create(FIRST_TEACHER_ID, schoolMeta);
                createdSpecialTeacher = true;
            } else {
                teacherMeta = TeacherMeta.createWithChainedId("teacher" + idNum, schoolMeta);
            }

            // it's useful to return the objects created JUST for this school
            // add to both maps here to avoid loop in map.putAll if we merged maps later
            teachersInSchoolMap.put(teacherMeta.id, teacherMeta);
            TEACHER_MAP.put(teacherMeta.id, teacherMeta);
        }

        return teachersInSchoolMap;
    }

    /**
     * Generate the students for this school.
     * studentsInSchoolMap is used later in this class.
     * STUDENT_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @return
     */
    private static Map<String, StudentMeta> buildStudentsForSchool(SchoolMeta schoolMeta) {

        Map<String, StudentMeta> studentsInSchoolMap = new HashMap<String, StudentMeta>(STUDENTS_PER_SCHOOL);
        for (int idNum = 0; idNum < STUDENTS_PER_SCHOOL; idNum++) {

            StudentMeta studentMeta = new StudentMeta("student" + idNum, schoolMeta);

            // it's useful to return the objects created JUST for this school
            // add to both maps here to avoid loop in map.putAll if we merged maps later
            studentsInSchoolMap.put(studentMeta.id, studentMeta);
            STUDENT_MAP.put(studentMeta.id, studentMeta);
        }

        return studentsInSchoolMap;
    }

    /**
     * Generate the courses for the school.
     * coursesForSchool is used later in this class.
     * COURSE_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @return
     */
    private static Map<String, CourseMeta> buildCoursesForSchool(SchoolMeta schoolMeta) {

        Map<String, CourseMeta> coursesForSchool = new HashMap<String, CourseMeta>(COURSES_PER_SCHOOL);

        for (int idNum = 0; idNum < COURSES_PER_SCHOOL; idNum++) {

            CourseMeta courseMeta = new CourseMeta("course" + idNum, schoolMeta);

            // it's useful to return the objects created JUST for this school
            // add to both maps here to avoid loop in map.putAll if we merged maps later
            coursesForSchool.put(courseMeta.id, courseMeta);
            COURSE_MAP.put(courseMeta.id, courseMeta);
        }

        return coursesForSchool;
    }

    /**
     * Generate the sessions for the school.
     * sessionsForSchool is used later in this class.
     * SESSION_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @return
     */
    private static Map<String, SessionMeta> buildSessionsForSchool(SchoolMeta schoolMeta) {

        Map<String, SessionMeta> sessionsForSchool = new HashMap<String, SessionMeta>(SESSIONS_PER_SCHOOL);

        for (int idNum = 0; idNum < SESSIONS_PER_SCHOOL; idNum++) {

            SessionMeta sessionMeta = new SessionMeta("session" + idNum, schoolMeta);

            // it's useful to return the objects created JUST for this school
            // add to both maps here to avoid loop in map.putAll if we merged maps later
            sessionsForSchool.put(sessionMeta.id, sessionMeta);
            SESSION_MAP.put(sessionMeta.id, sessionMeta);
        }

        return sessionsForSchool;
    }

    /**
     * Generate the sections for this school.
     * sectionMapForSchool is used later in this class.
     * SECTION_MAP is used to actually generate the XML.
     *
     * @param schoolMeta
     * @param coursesForSchool
     * @param sessionsForSchool
     * @param programsForSchool
     * @return
     */
    private static Map<String, SectionMeta> buildSectionsForSchool(SchoolMeta schoolMeta,
            Map<String, CourseMeta> coursesForSchool, Map<String, SessionMeta> sessionsForSchool,
            Map<String, ProgramMeta> programsForSchool) {

        Map<String, SectionMeta> sectionMapForSchool = new HashMap<String, SectionMeta>();

        Object[] programMetas = programsForSchool.values().toArray();
        int programCounter = 0;

        for (SessionMeta sessionMeta : sessionsForSchool.values()) {

            for (CourseMeta courseMeta : coursesForSchool.values()) {

                for (int idNum = 0; idNum < SECTIONS_PER_COURSE_SESSION; idNum++) {

                    // program reference in section is optional; will create one program reference
                    // for every inverse-probability-section-has-program section
                    ProgramMeta programMeta = null;
                    if (programMetas.length > 0 && sectionMapForSchool.size() % INV_PROB_SECTION_HAS_PROGRAM == 0) {
                        programMeta = (ProgramMeta) programMetas[programCounter];
                        programCounter = (programCounter + 1) % programMetas.length;
                    }

                    SectionMeta sectionMeta = new SectionMeta("section" + idNum, schoolMeta, courseMeta, sessionMeta,
                            programMeta);
{'fraction_non_alphanumeric': 0.08342961870990877, 'fraction_numerical': 0.0024702179369696002, 'mean_word_length': 2.98349468338359, 'pattern_counts': {'":': 0, '<': 133, '<?xml version=': 0, '>': 116, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '986849', 'n_tokens_mistral': 7620, 'n_tokens_neox': 7057, 'n_words': 1900}