import type UtilityNetwork from "./UtilityNetwork.js";
import type NetworkElement from "../rest/networks/support/NetworkElement.js";
import type UnitQueryResult from "../rest/networks/unitIdentifiers/support/UnitQueryResult.js";
import type { JSONSupport } from "../core/JSONSupport.js";
import type { UnitIdentifier } from "./support/jsonTypes.js";
import type { ServiceEdits } from "../rest/featureService/types.js";
import type { UtilityNetworkProperties } from "./UtilityNetwork.js";

export interface UnitIdentifierManagerProperties {
  /**
   * The [UtilityNetwork](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/) that contains the telecom
   * domain network being managed.
   */
  utilityNetwork?: UtilityNetworkProperties;
}

/**
 * A UnitIdentifierManager provides access to unit identifier management capabilities for a
 * telecom domain network in a utility network.
 *
 * @since 4.34
 * @see [UtilityNetwork](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/)
 * @see [CircuitManager](https://developers.arcgis.com/javascript/latest/references/core/networks/CircuitManager/)
 * @see [Telecom domain network](https://doc.esri.com/en/arcgis-pro/latest/help/data/utility-network/telecom-domain-networks.html)
 * @example
 * const utilityNetwork = new UtilityNetwork({
 *   layerUrl: "https://host.com/arcgis/rest/services/Test/FeatureServer/0",
 * });
 *
 * await utilityNetwork.load();
 *
 * const unitIdentifierManager = await utilityNetwork.getUnitIdentifierManager();
 */
export default class UnitIdentifierManager extends JSONSupport {
  constructor(properties?: UnitIdentifierManagerProperties);
  /**
   * Returns the root feature service URL which the utility network is part of.
   *
   * @example `https://utilitynetwork.esri.com/server/rest/services/NapervilleElectric/FeatureServer/`
   */
  get featureServiceUrl(): string;
  /**
   * The version of the geodatabase of the feature service data used by the utility network.
   * Read the [Overview of versioning](https://doc.esri.com/en/arcgis-pro/latest/help/data/geodatabases/overview/overview-of-versioning-in-arcgis-pro.html)
   * topic for more details about this capability.
   */
  get gdbVersion(): string | null | undefined;
  /**
   * The utility network's historic moment to query.
   * If this property is not specified, queries will apply to the current features.
   */
  get historicMoment(): Date | null | undefined;
  /**
   * The URL of the network server.
   *
   * @example `https://utilitynetwork.esri.com/server/rest/services/NapervilleElectric/UtilityNetworkServer/`
   */
  get networkServiceUrl(): string;
  /**
   * The [UtilityNetwork](https://developers.arcgis.com/javascript/latest/references/core/networks/UtilityNetwork/) that contains the telecom
   * domain network being managed.
   */
  get utilityNetwork(): UtilityNetwork;
  /**
   * Returns [ServiceEdits](https://developers.arcgis.com/javascript/latest/references/core/rest/featureService/types/#ServiceEdits) to combine [network elements](https://developers.arcgis.com/javascript/latest/references/core/rest/networks/support/NetworkElement/)
   * in a telecom domain network via the `applyEdits` method on the [FeatureService](https://developers.arcgis.com/javascript/latest/references/core/rest/featureService/FeatureService/) class.
   *
   * The objects being combined must have consecutive unit IDs, exist in the same table and unit container,
   * and have the same attribute values.
   *
   * @param networkElements - The network elements to combine in a telecom domain network.
   * @returns `ServiceEdits` for combining network elements in a telecom domain network.
   * @since 5.1
   * @example
   * const networkElementA = new NetworkElement({
   *   globalId: "{6CE34136-EC3A-40D7-80BF-E1D9BE33812A}",
   *   networkSourceId: 20,
   * });
   *
   * const networkElementB = new NetworkElement({
   *   globalId: "{74100804-E229-49b8-8CDC-9B5D3EF03EDA}",
   *   networkSourceId: 20,
   * });
   *
   * const networkElementC = new NetworkElement({
   *   globalId: "{39B856DC-AFE4-4c02-B433-A9361ACD91CF}",
   *   networkSourceId: 20,
   * });
   *
   * const serviceEdits = unitIdentifierManager.generateCombineNetworkElements([
   *   networkElementA,
   *   networkElementB,
   *   networkElementC,
   * ]);
   *
   * await featureService.applyEdits([serviceEdits]);
   */
  generateCombineNetworkElements(networkElements: NetworkElement[]): ServiceEdits;
  /**
   * Returns [ServiceEdits](https://developers.arcgis.com/javascript/latest/references/core/rest/featureService/types/#ServiceEdits) to divide a grouped [network element](https://developers.arcgis.com/javascript/latest/references/core/rest/networks/support/NetworkElement/)
   * in a telecom domain network into two or more grouped elements via the `applyEdits` method on the [FeatureService](https://developers.arcgis.com/javascript/latest/references/core/rest/featureService/FeatureService/) class.
   *
   * @param networkElement - The grouped network element in a telecom
   *   domain network to divide into two or more grouped elements.
   * @param numUnits - Describes how the unit identifiers of the grouped object should be divided.
   *   Each number in this array describes the number of units to assign an object resulting from the division.
   *   E.g., to divide one object with 6 units into an object with 5 units and another object with 1 unit, specify [5, 1].
   * @returns `ServiceEdits` for dividing a network element in a telecom domain network.
   * @since 5.1
   * @example
   * const networkElement = new NetworkElement({
   *   globalId: "{6CE34136-EC3A-40D7-80BF-E1D9BE33812A}",
   *   networkSourceId: 20,
   * });
   *
   * const serviceEdits = unitIdentifierManager.generateDivideNetworkElements(networkElement, [2, 3, 4]);
   *
   * await featureService.applyEdits([serviceEdits]);
   */
  generateDivideNetworkElements(networkElement: NetworkElement, numUnits: number[]): ServiceEdits;
  /**
   * Returns unit identifiers for, and existing gaps in, a unit container feature's containment hierarchy in a
   * telecom domain network.
   *
   * @param containers - The unit container features or objects to query.
   * @returns Resolves to an array of objects describing
   *   the unit identifiers and gaps for the specified unit containers.
   * @example
   * ```ts
   * const containers: UnitIdentifier[] = [
   *   {
   *     sourceId: 16,
   *     globalId: "{25B5F11B-70A2-4A61-9284-F0CE4C1E2111}",
   *   },
   * ];
   *
   * const results = await unitIdentifierManager.query(containers);
   * ```
   */
  query(containers: UnitIdentifier[]): Promise<UnitQueryResult[]>;
  /**
   * Shifts existing records in the containment hierarchy of a unit container's NextUnitID sequence
   * to reserve a range of unit IDs in a telecom domain network.
   *
   * When this range is inserted at the end of the sequence, the `NEXTUNITID` attribute value for the unit container increases.
   * If a range is inserted into the middle of an existing sequence to create a gap, the system will attempt to shift existing
   * records to accommodate the reserved space. The operation will fail and return an error if the reservation requires
   * regrouping an object or occurs in the middle of a connectivity assignment.
   *
   * @param container - The unit container to insert a gap into.
   * @param firstUnit - The first unit for the gap to be introduced.
   * @param lastUnit - The last unit for the gap to be introduced.
   * @returns Resolves when the gap is successfully inserted.
   * @example
   * ```ts
   * const container: UnitIdentifier = {
   *   sourceId: 16,
   *   globalId: "{25B5F11B-70A2-4A61-9284-F0CE4C1E2111}",
   * };
   *
   * await unitIdentifierManager.reserve(container, 2, 5);
   * ```
   */
  reserve(container: UnitIdentifier, firstUnit: number, lastUnit: number): Promise<void>;
  /**
   * Resets the unit identifiers associated with one or more unit container features in a telecom domain network.
   * This is done to condense the unit identifier space or overcome unit identifier sequence exhaustion.
   *
   * @param containers - The unit container features or objects to be reset.
   * @returns Resolves when the containers are successfully reset.
   * @example
   * ```ts
   * const containers: UnitIdentifier[] = [
   *   {
   *     sourceId: 16,
   *     globalId: "{25B5F11B-70A2-4A61-9284-F0CE4C1E2111}",
   *   },
   * ];
   *
   * await unitIdentifierManager.reset(containers);
   * ```
   */
  reset(containers: UnitIdentifier[]): Promise<void>;
  /**
   * Alters the number of units associated with a unit identifier feature in a telecom domain network.
   *
   * @param content - The unit identifiable feature or object being resized.
   * @param lastUnit - The last unit for the feature or object to be resized to.
   * @returns Resolves when the feature or object is successfully resized.
   * @example
   * ```ts
   * const content: UnitIdentifier = {
   *   sourceId: 16,
   *   globalId: "{25B5F11B-70A2-4A61-9284-F0CE4C1E2111}",
   * };
   *
   * await unitIdentifierManager.resize(content, 8);
   * ```
   */
  resize(content: UnitIdentifier, lastUnit: number): Promise<void>;
}