import type UNTraceConfiguration from "./UNTraceConfiguration.js";

export type UtilityNetworkFeatureClassUsageType = "esriUNFCUTDevice" | "esriUNFCUTJunction" | "esriUNFCUTLine" | "esriUNFCUTAssembly" | "esriUNFCUTSubnetLine" | "esriUNFCUTStructureJunction" | "esriUNFCUTStructureLine" | "esriUNFCUTStructureBoundary" | "esriUNFCUTJunctionObject" | "esriUNFCUTEdgeObject" | "esriUNFCUTStructureJunctionObject" | "esriUNFCUTStructureEdgeObject" | "esriUNFCUTCircuit" | "esriUNFCUTCircuitSection" | "esriUNFCUTSubcircuit";

export type PolicyType = "esriDPTUnitApportioned" | "esriDPTDefaultValue" | "esriCPTSumValues" | "esriCPTDefaultValue";

/**
 * Uniquely identifies an element by network source ID and global ID.
 *
 * @since 4.34
 */
export interface UnitIdentifier {
  /** The element's global ID. */
  globalId: string;
  /** The element's network source ID. */
  sourceId: number;
}

/**
 * A range of unit identifiers in a container feature or object's containment hierarchy.
 *
 * @since 4.34
 */
export interface UnitRange {
  /** The object consuming the unit identifiers in this range. */
  content?: UnitIdentifier | null;
  /** The unit offset in the grouped object. */
  firstUnit: number;
  /** Whether the unit identifier range is a gap, i.e., is not utilized. */
  isGap: boolean;
  /** The last unit in the unit identifier range. */
  lastUnit: number;
}

/**
 * Results returned from the [CircuitManager#export()](https://developers.arcgis.com/javascript/latest/api-reference/esri-networks-CircuitManager.html#export) method.
 *
 * @since 4.34
 */
export interface CircuitExportResult {
  /** Indicates if the circuit has been logically deleted. */
  circuitHasBeenDeleted: boolean;
  /** The name of the exported circuit. */
  circuitName: string;
  /** Optional error information if the export failed. */
  error?: CircuitExportResultError;
  /** Indicates if the export was successful. */
  success: boolean;
  /** The location of the exported circuit JSON file. */
  url: string;
}

export interface CircuitExportResultError {
  /** Additional error details. */
  details: string[];
  /** Extended error code. */
  extendedCode: number;
  /** Error message. */
  message: string;
}

/**
 * AssetTypeJSON represents [asset type](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/utility-feature-classification.htm#GUID-A4CCEB96-C4F8-459B-A763-FF6A5791F663).
 * Attribute domains are assigned on the asset type field at the subtype level for each network class. It represents the minor classification of the utility network classes.
 */
export interface AssetTypeJSON {
  /** The unique code for the asset type. */
  assetTypeCode: number;
  /** The name of the asset type. */
  assetTypeName?: string;
  /** The connectivity policy applied to the asset type. */
  connectivityPolicy?: string;
  /** Indicates if terminal configurations are supported for the asset type. */
  isTerminalConfigurationSupported?: boolean;
  /** The terminal configuration ID associated with the asset type, if applicable. */
  terminalConfigurationId?: number;
}

/**
 * AssetGroupJSON represents the [asset group](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/utility-feature-classification.htm#GUID-A4CCEB96-C4F8-459B-A763-FF6A5791F663).
 * The asset group is the subtype field and represents the major classification of utility network classes.
 */
export interface AssetGroupJSON {
  /** The unique code for the asset group. */
  assetGroupCode: number;
  /** The asset group name. */
  assetGroupName?: string;
  /** An array of asset types associated with the asset group. */
  assetTypes: AssetTypeJSON[];
}

export interface CircuitSourceJSON {
  /** The layer id of the point layer. */
  layerId: number;
  /** The network source id of the layer. */
  sourceId: number;
  /** The usage type of the edge source. */
  utilityNetworkFeatureClassUsageType: UtilityNetworkFeatureClassUsageType;
}

/** JunctionSourceJSON represents the point layers that participate in the utility network service. */
export interface NetworkSourceJSON extends CircuitSourceJSON {
  /** The asset group attribute values for the point layer. */
  assetGroups: AssetGroupJSON[];
  /** Supported properties for the edge source. */
  supportedProperties: string[];
}

/**
 * Describes a domain network in a utility network data element.
 *
 * @since 4.34
 */
export interface DomainNetworkJSON {
  /** Circuit properties for telecom networks. */
  circuitProperties?: CircuitPropertiesJSON | null;
  /** An array of circuit source objects for telecom networks. */
  circuitSources?: CircuitSourceJSON[] | null;
  /** An array of objects to describe color schemes in a telecom domain network. */
  colorSchemes?: ColorSchemeJSON[] | null;
  /** An array of objects describing combine policies. */
  combinePolicies?: PolicyJSON[] | null;
  /** An array of objects describing divide policies for a telecom domain network. */
  dividePolicies?: PolicyJSON[] | null;
  /** The name of the domain network. */
  domainNetworkName: string;
  /** An array of network source objects that represent the sources of edge features. */
  edgeSources: NetworkSourceJSON[];
  /** Indicates if this domain network is a structure network. */
  isStructureNetwork: boolean;
  /** Indicates if this domain network is a telecom domain network. */
  isTelecomNetwork: boolean;
  /** An array of network source objects that represent the sources of junction features. */
  junctionSources: NetworkSourceJSON[];
  /** The layer ID of the subnetwork layer. Null if no subnetwork layer is defined, e.g., a telecom domain network. */
  subnetworkLayerId?: number | null;
  /** An array of tier definitions used to organize the network into hierarchical levels. Null if no tiers are defined, e.g., a telecom domain network. */
  tiers?: TierJSON[] | null;
  /**
   * A UNTraceConfiguration object that defines the trace configuration for the domain network.
   *   This configuration includes parameters specific to utility networks.
   */
  traceConfiguration?: UNTraceConfiguration | null;
}

export interface CircuitPropertiesJSON {
  /** The items in the property set. */
  propertySetItems: (string | boolean)[];
  /** The type of the property set. */
  type: "PropertySet";
}

export interface ColorSchemeJSON {
  /** The group delimiter. */
  groupDelimiter: string;
  /** An array of objects representing color groups in the color scheme. */
  groups: ColorGroupJSON[];
  /** The id of the color scheme. */
  id: number;
  /** The number of levels in the color scheme. */
  levels: number;
  /** The name of the color scheme. */
  name: string;
}

export interface ColorGroupJSON {
  /** The capacity for the color group. */
  capacity: number[];
  /** The delimiter for the color group. */
  delimiter: string;
  /** The labels for the color group. */
  labels: (string | number)[];
  /** The level of the color group. */
  level: number;
  /** The name of the color group. */
  name: string;
}

export interface PolicyJSON {
  /** The attribute name for the policy. */
  attributeName: string;
  /** The policy type. */
  policy: PolicyType;
  /** The source ID for the policy. */
  sourceId: number;
}

export interface TierJSON {
  /** The name of the tier. */
  name: string;
}

export interface TerminalConfigurationJSON {
  /** The Id that uniquely identifies the terminal configuration. */
  terminalConfigurationId: number;
}

/**
 * Contains the full network definition.
 *
 * @since 4.33
 */
export interface NetworkDataElementJSON {
  /** An array of domain networks included in the utility network. */
  domainNetworks: DomainNetworkJSON[];
  /** The name of the utility network. */
  name: string;
  /** The schema generation version number of the utility network. */
  schemaGeneration: number;
  /** The layer Id of the feature layer representing service territories within the network. */
  serviceTerritoryFeatureLayerId: number;
  /** An array of terminal configuration objects available in the network. */
  terminalConfigurations: TerminalConfigurationJSON[];
  /** The user identity associated with the network definition. */
  userIdentity: string;
}

/**
 * ResultTypeJSON specifies the type of results to return after running a trace.
 *
 * @example
 * // Creates a new instance of this class and initializes it with values inputted in json format. A resultTypes object is passed into the resultTypes property.
 * const traceParameters = TraceParameters.fromJSON({
 *    traceConfigurationGlobalId: "{DF22DA8D-6EC0-408B-A8B2-E468EC7DC9BF}",
 *    moment: 1554214441244,
 *    gdbVersion: "SDE.DEFAULT",
 *    resultTypes: [
 *      {
 *        type: "elements",
 *        includeGeometry: false,
 *        includePropagatedValues: false,
 *        networkAttributeNames: [],
 *        diagramTemplateName: "",
 *        resultTypeFields: []
 *      },
 *      {
 *        type: "aggregatedGeometry",
 *        includeGeometry: false,
 *        includePropagatedValues: false,
 *        networkAttributeNames: [],
 *        diagramTemplateName: "",
 *        resultTypeFields: []
 *      }
 *    ],
 *    traceType: "subnetwork"
 *  });
 */
export interface ResultType {
  /** Specifies the name of a predefined Diagram Template. */
  diagramTemplateName: string;
  /** Specifies whether to return geometry values in resultTypes. */
  includeGeometry: boolean;
  /** Specifies whether to return propagated values in resultTypes. */
  includePropagatedValues: boolean;
  /** Specifies the network attribute names. */
  networkAttributeNames: string[];
  /** Specifies the types of output fields that can be generated from geoprocessing tools. */
  resultTypeFields: Object[];
  /** Specifies the return type for the trace. `paths` and `circuits` are reserved for future use. */
  type: "elements" | "aggregatedGeometry" | "paths" | "circuits";
}

/**
 * ValidationSetItemJSON represents the set of features and objects to validate.
 *
 * @example
 * const validationResult = await network.submitTopologyValidationJob(
 *   new ValidateNetworkTopologyParameters({
 *     validateArea: extent,
 *     gdbVersion: "sde.DEFAULT",
 *     validationType: "rebuild",
 *     sessionID: "{7865BAA6-ED9C-4346-9F72-894A49E10C73}",
 *     validationSet: [
 *       {
 *         sourceId: 4134325151,
 *         globalIds: ["{7865BAA6-ED9C-4346-9F72-894A49E10C73}"]
 *       }
 *     ]
 *   })
 * );
 *
 * console.log("result: ", validationResult);
 */
export interface ValidationSetItemJSON {
  /** An array of globalId strings to validate. */
  globalIds: string[];
  /** The network source id of the. */
  sourceId: number;
}