import type SpatialReference from "../../geometry/SpatialReference.js";
import type Domain from "../../layers/support/Domain.js";
import type EntityType from "./EntityType.js";
import type RelationshipType from "./RelationshipType.js";
import type SearchIndex from "./SearchIndex.js";
import type SourceTypeValueBehavior from "./SourceTypeValueBehavior.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { EsriIdentifierInfoTypes, EsriUuidMethodHintType } from "./types.js";
import type { DomainProperties } from "../../layers/support/Domain.js";

export interface DataModelProperties {
  /** Specifies a default value for the object type. */
  domains?: DomainProperties[];
}

/**
 * The data model defines the [entity types](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/EntityType/)
 * and [relationship types](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/RelationshipType/) in a
 * [knowledge graph service](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraphService/) as well as some additional settings.
 * The DataModel resource allows users to query the properties of both entity and relationship types.
 * By defining these types and their properties, the data model defines the schema of the graph.
 *
 * Sample of a knowledge graph data model.
 * ```js
 *  {
 *  	"dataModel": {
 *  		"declaredClass": "esri.rest.knowledgeGraph.DataModel",
 *  		"arcgisManaged": true,
 *  		"globalIdField": "globalid",
 *  		"identifierInfo": {
 *  			"IdentifierMappingInfo": {
 *  				"databaseNativeIdentifier": null,
 *  				"identifierInfoType": "esriIdentifierInfoTypeUniformProperty",
 *  				"uniformPropertyIdentifier": {
 *  					"identifierPropertyName": "globalid"
 *  				}
 *  			},
 *  			"identifierGenerationInfo": {
 *  				"uuidMethodHint": "esriUUIDESRI"
 *  			}
 *  		},
 *  		"timestamp": {},
 *  		"spatialReference": {
 *  			"latestWkid": 0,
 *  			"wkid": 4326,
 *  			"vcsWkid": 0,
 *  			"latestVcsWkid": 0
 *  		},
 *  		"strict": false,
 *  		"searchIndexes:": [
 *  			{
 *  				"analyzers": [
 *  					{
 *  						"name": "text_en"
 *  					}
 *  				],
 *  				"name": "esri__search_idx",
 *  				"searchProperties": [
 *  					{
 *  						"key": "Person",
 *  						"value": {
 *  							"propertyNames": [
 *  								"name",
 *  								"age"
 *  							]
 *  						}
 *  					}
 *  				],
 *  				"supportedCategory": null
 *  			}
 *  		],
 *  		"entityTypes": [
 *  			{
 *  				"declaredClass": "esri.rest.knowledgeGraph.EntityType",
 *  				"name": "company",
 *  				"alias": "Company",
 *  				"role": "Regular",
 *  				"strict": false,
 *  				"properties": [
 *  					{
 *  						"declaredClass": "esri.rest.knowledgeGraph.GraphProperty",
 *  						"name": "Name",
 *  						"alias": "Name",
 *  						"fieldType": "esriFieldTypeString",
 *  						"geometryType": "esriGeometryNull",
 *  						"hasM": false,
 *  						"hasZ": false,
 *  						"nullable": true,
 *  						"editable": true,
 *  						"required": false,
 *  						"defaultVisibility": true,
 *  						"systemMaintained": false,
 *  						"role": "esriGraphPropertyRegular",
 *  						"defaultValue": null
 *  					},
 *  					{
 *  						"declaredClass": "esri.rest.knowledgeGraph.GraphProperty",
 *  						"name": "id",
 *  						"alias": "id",
 *  						"fieldType": "esriFieldTypeOID",
 *  						"geometryType": "esriGeometryNull",
 *  						"hasM": false,
 *  						"hasZ": false,
 *  						"nullable": false,
 *  						"editable": false,
 *  						"required": true,
 *  						"defaultVisibility": true,
 *  						"systemMaintained": true,
 *  						"role": "esriGraphPropertyRegular",
 *  						"defaultValue": null
 *  					}
 *  				],
 *  				"fieldIndexes": [
 *  					{
 *  						"declaredClass": "esri.rest.knowledgeGraph.FieldIndex",
 *  						"name": "esri__id_idx",
 *  						"unique": true,
 *  						"ascending": true,
 *  						"description": "",
 *  						"fieldNames": [
 *  							"id"
 *  						]
 *  					},
 *  					{
 *  						"declaredClass": "esri.rest.knowledgeGraph.FieldIndex",
 *  						"name": "esri__name_idx",
 *  						"unique": true,
 *  						"ascending": true,
 *  						"description": "",
 *  						"fieldNames": [
 *  							"name"
 *  						]
 *  					}
 *  				]
 *  			}
 *  		],
 *  		"relationshipTypes": [
 *  			{
 *  				"declaredClass": "esri.rest.knowledgeGraph.RelationshipType",
 *  				"name": "employed_by",
 *  				"alias": "Employed By",
 *  				"role": "Regular",
 *  				"strict": false,
 *  				"properties": [
 *  					{
 *  						"declaredClass": "esri.rest.knowledgeGraph.GraphProperty",
 *  						"name": "id",
 *  						"alias": "id",
 *  						"fieldType": "esriFieldTypeGUID",
 *  						"geometryType": "esriGeometryNull",
 *  						"hasM": false,
 *  						"hasZ": false,
 *  						"nullable": false,
 *  						"editable": false,
 *  						"required": true,
 *  						"defaultVisibility": true,
 *  						"systemMaintained": true,
 *  						"role": "esriGraphPropertyRegular",
 *  						"defaultValue": null
 *  					},
 *  					{
 *  						"declaredClass": "esri.rest.knowledgeGraph.GraphProperty",
 *  						"name": "start_date",
 *  						"alias": "Start Date",
 *  						"fieldType": "esriFieldTypeDate",
 *  						"geometryType": "esriGeometryNull",
 *  						"hasM": false,
 *  						"hasZ": false,
 *  						"nullable": false,
 *  						"editable": false,
 *  						"required": true,
 *  						"defaultVisibility": true,
 *  						"systemMaintained": false,
 *  						"role": "esriGraphPropertyRegular",
 *  						"defaultValue": null
 *  					}
 *  				],
 *  				"fieldIndexes": [
 *  					{
 *  						"ascending": true,
 *  						"description": "index on id field",
 *  						"fieldNames": [
 *  							"id"
 *  						],
 *  						"name": "esri_id_idx",
 *  						"unique": "true"
 *  					}
 *  				],
 *  				"endpoints": [
 *  					{
 *  						"originEntityType": "Person",
 *  						"destinationEntityType": "Company"
 *  					}
 *  				]
 *  			}
 *  		]
 *  	}
 *  }
 * ```
 *
 * @since 4.25
 * @see [EntityType](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/EntityType/)
 * @see [RelationshipType](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/RelationshipType/)
 * @see [fetchKnowledgeGraph()](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraphService/#fetchKnowledgeGraph)
 * @see [refreshDataModel()](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraphService/#refreshDataModel)
 */
export default class DataModel extends JSONSupport {
  constructor(properties?: DataModelProperties);
  /**
   * Indicates if the data in the graph is managed by ArcGIS Knowledge. This is `true` for hosted knowledge graph
   * services and ArcGIS managed external data stores where ArcGIS Knowledge can create, update and delete data.
   * This property is `false` for user managed external graph stores, in which the data and data model are read only from ArcGIS Knowledge.
   *
   * > [!WARNING]
   * >
   * > **Note**
   * >
   * > Currently the only supported external graph store is [Neo4j](https://neo4j.com/)
   */
  get arcgisManaged(): boolean;
  /** Specifies a default value for the object type. */
  get domains(): Domain[];
  set domains(value: DomainProperties[]);
  /** A list of the [entity types](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/EntityType/) contained in the knowledge graph including their associated properties. */
  get entityTypes(): EntityType[];
  /**
   * Information about the global ID for the knowledge graph.
   *
   * @example
   * "identifierInfo": {
   *  	"IdentifierMappingInfo": {
   *  		"databaseNativeIdentifier": null,
   *  		"identifierInfoType": "esriIdentifierInfoTypeUniformProperty",
   *  		"uniformPropertyIdentifier": {
   *  			"identifierPropertyName": "globalid"
   *  		}
   *  	},
   *  	"identifierGenerationInfo": {
   *  		"uuidMethodHint": "esriUUIDESRI"
   *  	}
   *  }
   */
  get identifierInfo(): DataModelIdentifierInfo;
  /**
   * A list of the meta entity types in the knowledge graph and their associated properties.
   * `metaEntityTypes` are types that store information about the records, or specific properties on records in the graph.
   * For example, provenance tracks where information in the knowledge graph originated. Each provenance record associates
   * the value stored in a property of an `entity` or a `relationship` with a specific source.
   *
   * @since 4.30
   */
  get metaEntityTypes(): EntityType[];
  /**
   * A list of the provenance source type values and their behaviors in the knowledge graph.
   *
   * @since 4.31
   */
  get provenanceSourceTypeValues(): SourceTypeValueBehavior[];
  /** A list of the [relationship types](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/RelationshipType/) in the knowledge graph including their associated properties. */
  get relationshipTypes(): RelationshipType[];
  /** List of the [search indexes](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraph/SearchIndex/) in the knowledge graph. */
  get searchIndexes(): SearchIndex[];
  /** Specifies [spatial reference](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/) information for the knowledge graph. */
  get spatialReference(): SpatialReference | null | undefined;
  /**
   * Indicates whether users can make changes to the data model. If `true`, the data model cannot be modified and
   * [executeApplyEdits()](https://developers.arcgis.com/javascript/latest/references/core/rest/knowledgeGraphService/#executeApplyEdits) will fail.
   * If `false`, any user can make changes to the data model.
   * The strict property of the data model can only be set by administrators or the knowledge graph service owner from the ArcGIS REST API [Update (Edit Data Model)](https://developers.arcgis.com/rest/services-reference/enterprise/kgs-datamodel-edit-update-admin.htm).
   */
  get strict(): boolean | null | undefined;
  /** The date the data model was last updated. */
  get timestamp(): Date;
}

export interface DataModelIdentifierInfo {
  /** Information on the type and format of the universally unique identifier */
  identifierMappingInfo: DataModelIdentifierInfoIdentifierMappingInfo;
  /** Information on how the unique identifier is generated. */
  identifierGenerationInfo: DataModelIdentifierInfoIdentifierGenerationInfo;
}

export interface DataModelIdentifierInfoIdentifierMappingInfo {
  /**
   * Indicates the type of the ID.
   * `esriIdentifierInfoTypeDatabaseNative` is a durable, settable database native identifier.
   * `esriIdentifierInfoTypeUniformProperty` is a user-defined property that guarantees named type category uniqueness & is uniformly named across the graph.
   */
  identifierInfoType: EsriIdentifierInfoTypes;
  /** Properties of database native identifier. */
  databaseNativeIdentifier: {};
  /** Properties of the user defined unique identifier. */
  uniformPropertyIdentifier: DataModelIdentifierInfoIdentifierMappingInfoUniformPropertyIdentifier;
}

export interface DataModelIdentifierInfoIdentifierMappingInfoUniformPropertyIdentifier {
  /** The name of the unique identifier property for all records. */
  identifierPropertyName: string;
}

export interface DataModelIdentifierInfoIdentifierGenerationInfo {
  /**
   * Information on the format of the unique identifier. `esriUUIDESRI` is a universally unique ID in Esri/Microsoft format: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
   * `UUID_RFC_4122` is a universally unique ID in [RFC4122](https://www.rfc-editor.org/rfc/rfc4122) lowercase format.
   */
  uuidMethodHint: EsriUuidMethodHintType;
}