/*
 * 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 {SCMap, SCRestrictedMap} from '../general/map.js';
import {SCUuid} from '../general/uuid.js';
import {SCSearchSortType} from '../protocol/search/sort.js';
import {SCThingType} from '../things/abstract/thing.js';
import {SCMonitoringConfiguration} from './monitoring.js';

/**
 * A backend configuration
 */
export interface SCBackendConfiguration {
  /**
   * The maximum amount of time (milliseconds) an external program can take to provide a response to the backend
   *
   * This can be used for example for Plugins.
   */
  externalRequestTimeout: number;

  /**
   * A list of hidden SC types
   *
   * If a type is hidden it won't show in any result unless the type is filtered for
   *
   */
  hiddenTypes: SCThingType[];

  /**
   * A list of tags that will be ignored by the mapping generator
   *
   * The ignored tags should mainly be tags that are irrelevant to the mapping. The tags should include the '@'.
   */
  mappingIgnoredTags: string[];

  /**
   * Maximum number of queries, that can be used in MultiSearchRoute
   */
  maxMultiSearchRouteQueries: number;

  /**
   * Maximum body size for requests
   */
  maxRequestBodySize: number;

  /**
   * Name of university
   */
  name: string;

  /**
   * Namespace of the university for UID generation
   */
  namespace: SCUuid;

  /**
   * Version string of the installed StAppsCore
   */
  SCVersion: string;

  /**
   * A list of sortable fields of each type
   */
  sortableFields: SCBackendConfigurationSortableField[];
}

/**
 * Description which sort types are supported on which fields of which types
 */
export interface SCBackendConfigurationSortableField {
  /**
   * Field name which the sorts should be available on
   */
  fieldName: string;

  /**
   * A list of SC types on which this field exists
   *
   * If no type is given it is assumed it exists on every type
   */
  onlyOnTypes?: SCThingType[];

  /**
   * A list of supported sorts on this field
   */
  sortTypes: SCSearchSortType[];
}

/**
 * Possible context names to be used by the search request
 */
export type SCSearchContext = 'default' | 'dining' | 'place';

/**
 * A boosting configuration for one context
 */
export type SCBackendConfigurationSearchBoostingContext = SCRestrictedMap<
  SCSearchContext,
  SCBackendConfigurationSearchBoostingType[]
>;

/**
 * A boosting configuration for one SCType
 */
export interface SCBackendConfigurationSearchBoostingType {
  /**
   * The factor of which the scores matching this type should be multiplied by
   */
  factor: number;

  /**
   * Outer-Map:
   * Fields of this type that should be boosted if they match a given value
   * For nest fields you can use the `.` as a separator. For example `academicTerms.acronym`
   *
   * Inner-map:
   * Value of the field that should be boosted by the given number
   * For example `"SS 2019": 2`
   */
  fields?: SCMap<SCMap<number>>;

  /**
   * Type of things the factor should be applied to
   */
  type: SCThingType;
}

/**
 * Describes which field on which type should be aggregated
 */
export interface SCBackendAggregationConfiguration {
  /**
   * Field name of field which values should be aggregated
   */
  fieldName: string;

  /**
   * A list of SC types of which the field is on
   *
   * If the type is not given is is assumed the field exists on every type
   */
  onlyOnTypes?: SCThingType[];
}

/**
 * The internal backend configuration that is hidden from the app
 */
export interface SCBackendInternalConfiguration {
  /**
   * A list of configurations for aggregations
   */
  aggregations: SCBackendAggregationConfiguration[];

  /**
   * A list of configurations for search boosting
   *
   * The resulting scores of matching objects can be boosted (multiplied by a number) to change the order in the
   * set of results
   */
  boostings: SCBackendConfigurationSearchBoostingContext;

  /**
   * Configuration of the database
   */
  database?: SCBackendConfigurationDatabaseConfiguration;

  /**
   * Configuration for monitoring
   */
  monitoring?: SCMonitoringConfiguration;
}

/**
 * Configuration of the database
 */
export interface SCBackendConfigurationDatabaseConfiguration extends SCMap<unknown> {
  /**
   * Name of the database used by the backend
   */
  name: string;
}
