/*
 * Copyright (C) 2019-2022 Open StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */
import {SCThingType} from './things/abstract/thing.js';
import {
  SCAcademicEvent,
  SCAcademicEventMeta,
  SCAcademicEventWithoutReferences,
} from './things/academic-event.js';
import {SCArticle, SCArticleMeta, SCArticleWithoutReferences} from './things/article.js';
import {SCAssessment, SCAssessmentMeta, SCAssessmentWithoutReferences} from './things/assessment.js';
import {SCBook, SCBookMeta, SCBookWithoutReferences} from './things/book.js';
import {SCBuilding, SCBuildingMeta, SCBuildingWithoutReferences} from './things/building.js';
import {SCCatalog, SCCatalogMeta, SCCatalogWithoutReferences} from './things/catalog.js';
import {
  SCCertification,
  SCCertificationMeta,
  SCCertificationWithoutReferences,
} from './things/certification.js';
import {SCContactPoint, SCContactPointMeta, SCContactPointWithoutReferences} from './things/contact-point.js';
import {
  SCCourseOfStudy,
  SCCourseOfStudyMeta,
  SCCourseOfStudyWithoutReferences,
} from './things/course-of-study.js';
import {SCDateSeries, SCDateSeriesMeta, SCDateSeriesWithoutReferences} from './things/date-series.js';
import {SCDiff, SCDiffMeta, SCDiffWithoutReferences} from './things/diff.js';
import {SCDish, SCDishMeta, SCDishWithoutReferences} from './things/dish.js';
import {SCFavorite, SCFavoriteMeta, SCFavoriteWithoutReferences} from './things/favorite.js';
import {SCFloor, SCFloorMeta, SCFloorWithoutReferences} from './things/floor.js';
import {SCIdCard, SCIdCardMeta, SCIdCardWithoutReferences} from './things/id-card.js';
import {SCJobPosting, SCJobPostingMeta, SCJobPostingWithoutReferences} from './things/job-posting.js';
import {SCMessage, SCMessageMeta, SCMessageWithoutReferences} from './things/message.js';
import {SCOrganization, SCOrganizationMeta, SCOrganizationWithoutReferences} from './things/organization.js';
import {SCPeriodical, SCPeriodicalMeta, SCPeriodicalWithoutReferences} from './things/periodical.js';
import {SCPerson, SCPersonMeta, SCPersonWithoutReferences} from './things/person.js';
import {
  SCPointOfInterest,
  SCPointOfInterestMeta,
  SCPointOfInterestWithoutReferences,
} from './things/point-of-interest.js';
import {
  SCPublicationEvent,
  SCPublicationEventMeta,
  SCPublicationEventWithoutReferences,
} from './things/publication-event.js';
import {SCRoom, SCRoomMeta, SCRoomWithoutReferences} from './things/room.js';
import {SCSemester, SCSemesterMeta, SCSemesterWithoutReferences} from './things/semester.js';
import {SCSetting, SCSettingMeta, SCSettingWithoutReferences} from './things/setting.js';
import {SCSportCourse, SCSportCourseMeta, SCSportCourseWithoutReferences} from './things/sport-course.js';
import {SCStudyModule, SCStudyModuleMeta, SCStudyModuleWithoutReferences} from './things/study-module.js';
import {SCTicket, SCTicketMeta, SCTicketWithoutReferences} from './things/ticket.js';
import {SCToDo, SCToDoMeta, SCToDoWithoutReferences} from './things/todo.js';
import {SCTour, SCTourMeta, SCTourWithoutReferences} from './things/tour.js';
import {SCVideo, SCVideoMeta, SCVideoWithoutReferences} from './things/video.js';

/**
 * A map of things, from type to meta data
 */
export const SCClasses: {[K in SCThingType]: object} = {
  'assessment': SCAssessmentMeta,
  'academic event': SCAcademicEventMeta,
  'article': SCArticleMeta,
  'book': SCBookMeta,
  'building': SCBuildingMeta,
  'catalog': SCCatalogMeta,
  'contact point': SCContactPointMeta,
  'course of study': SCCourseOfStudyMeta,
  'date series': SCDateSeriesMeta,
  'diff': SCDiffMeta,
  'dish': SCDishMeta,
  'favorite': SCFavoriteMeta,
  'floor': SCFloorMeta,
  'id card': SCIdCardMeta,
  'message': SCMessageMeta,
  'organization': SCOrganizationMeta,
  'periodical': SCPeriodicalMeta,
  'person': SCPersonMeta,
  'point of interest': SCPointOfInterestMeta,
  'publication event': SCPublicationEventMeta,
  'room': SCRoomMeta,
  'semester': SCSemesterMeta,
  'setting': SCSettingMeta,
  'sport course': SCSportCourseMeta,
  'study module': SCStudyModuleMeta,
  'ticket': SCTicketMeta,
  'todo': SCToDoMeta,
  'tour': SCTourMeta,
  'video': SCVideoMeta,
  'certification': SCCertificationMeta,
  'job posting': SCJobPostingMeta,
};

export type SCIndexableThings =
  | SCAssessment
  | SCAcademicEvent
  | SCArticle
  | SCBook
  | SCBuilding
  | SCCatalog
  | SCContactPoint
  | SCCourseOfStudy
  | SCCertification
  | SCDateSeries
  | SCDish
  | SCFloor
  | SCIdCard
  | SCMessage
  | SCOrganization
  | SCPeriodical
  | SCPerson
  | SCPointOfInterest
  | SCPublicationEvent
  | SCRoom
  | SCSemester
  | SCSportCourse
  | SCStudyModule
  | SCTicket
  | SCToDo
  | SCTour
  | SCVideo
  | SCJobPosting;

/**
 * An object that exists in the StAppsCore
 */
export type SCThings = SCIndexableThings | SCDiff | SCFavorite | SCSetting;

/**
 * A field of a thing
 */
export type SCThingsField = keyof SCThings | string;

/**
 * Thing without references for a thing
 */
export type SCAssociatedThingWithoutReferences<THING extends SCThings> = THING extends SCAssessment
  ? SCAssessmentWithoutReferences
  : THING extends SCAcademicEvent
    ? SCAcademicEventWithoutReferences
    : THING extends SCArticle
      ? SCArticleWithoutReferences
      : THING extends SCBook
        ? SCBookWithoutReferences
        : THING extends SCBuilding
          ? SCBuildingWithoutReferences
          : THING extends SCCatalog
            ? SCCatalogWithoutReferences
            : THING extends SCContactPoint
              ? SCContactPointWithoutReferences
              : THING extends SCCourseOfStudy
                ? SCCourseOfStudyWithoutReferences
                : THING extends SCCertification
                  ? SCCertificationWithoutReferences
                  : THING extends SCDateSeries
                    ? SCDateSeriesWithoutReferences
                    : THING extends SCDiff
                      ? SCDiffWithoutReferences
                      : THING extends SCDish
                        ? SCDishWithoutReferences
                        : THING extends SCFavorite
                          ? SCFavoriteWithoutReferences
                          : THING extends SCFloor
                            ? SCFloorWithoutReferences
                            : THING extends SCIdCard
                              ? SCIdCardWithoutReferences
                              : THING extends SCJobPosting
                                ? SCJobPostingWithoutReferences
                                : THING extends SCMessage
                                  ? SCMessageWithoutReferences
                                  : THING extends SCOrganization
                                    ? SCOrganizationWithoutReferences
                                    : THING extends SCPeriodical
                                      ? SCPeriodicalWithoutReferences
                                      : THING extends SCPerson
                                        ? SCPersonWithoutReferences
                                        : THING extends SCPointOfInterest
                                          ? SCPointOfInterestWithoutReferences
                                          : THING extends SCPublicationEvent
                                            ? SCPublicationEventWithoutReferences
                                            : THING extends SCRoom
                                              ? SCRoomWithoutReferences
                                              : THING extends SCSemester
                                                ? SCSemesterWithoutReferences
                                                : THING extends SCSetting
                                                  ? SCSettingWithoutReferences
                                                  : THING extends SCSportCourse
                                                    ? SCSportCourseWithoutReferences
                                                    : THING extends SCStudyModule
                                                      ? SCStudyModuleWithoutReferences
                                                      : THING extends SCTicket
                                                        ? SCTicketWithoutReferences
                                                        : THING extends SCToDo
                                                          ? SCToDoWithoutReferences
                                                          : THING extends SCTour
                                                            ? SCTourWithoutReferences
                                                            : THING extends SCVideo
                                                              ? SCVideoWithoutReferences
                                                              : never;

/**
 * Thing for a thing without references
 */
export type SCAssociatedThing<THING extends SCThings> = THING extends SCAssessmentWithoutReferences
  ? SCAssessment
  : THING extends SCAcademicEventWithoutReferences
    ? SCAcademicEvent
    : THING extends SCArticleWithoutReferences
      ? SCArticle
      : THING extends SCBookWithoutReferences
        ? SCBook
        : THING extends SCBuildingWithoutReferences
          ? SCBuilding
          : THING extends SCCatalogWithoutReferences
            ? SCCatalog
            : THING extends SCContactPointWithoutReferences
              ? SCContactPoint
              : THING extends SCCourseOfStudyWithoutReferences
                ? SCCourseOfStudy
                : THING extends SCCertificationWithoutReferences
                  ? SCCertification
                  : THING extends SCDateSeriesWithoutReferences
                    ? SCDateSeries
                    : THING extends SCDiffWithoutReferences
                      ? SCDiff
                      : THING extends SCDishWithoutReferences
                        ? SCDish
                        : THING extends SCJobPostingWithoutReferences
                          ? SCJobPosting
                          : THING extends SCFavoriteWithoutReferences
                            ? SCFavorite
                            : THING extends SCFloorWithoutReferences
                              ? SCFloor
                              : THING extends SCIdCardWithoutReferences
                                ? SCIdCard
                                : THING extends SCMessageWithoutReferences
                                  ? SCMessage
                                  : THING extends SCOrganizationWithoutReferences
                                    ? SCOrganization
                                    : THING extends SCPeriodicalWithoutReferences
                                      ? SCPeriodical
                                      : THING extends SCPersonWithoutReferences
                                        ? SCPerson
                                        : THING extends SCPointOfInterestWithoutReferences
                                          ? SCPointOfInterest
                                          : THING extends SCPublicationEventWithoutReferences
                                            ? SCPublicationEvent
                                            : THING extends SCRoomWithoutReferences
                                              ? SCRoom
                                              : THING extends SCSemesterWithoutReferences
                                                ? SCSemester
                                                : THING extends SCSettingWithoutReferences
                                                  ? SCSetting
                                                  : THING extends SCSportCourseWithoutReferences
                                                    ? SCSportCourse
                                                    : THING extends SCStudyModuleWithoutReferences
                                                      ? SCStudyModule
                                                      : THING extends SCTicketWithoutReferences
                                                        ? SCTicket
                                                        : THING extends SCToDoWithoutReferences
                                                          ? SCToDo
                                                          : THING extends SCTourWithoutReferences
                                                            ? SCTour
                                                            : THING extends SCVideoWithoutReferences
                                                              ? SCVideo
                                                              : never;
