import type CircuitManager from "../CircuitManager.js";
import type CircuitLocation from "./CircuitLocation.js";
import type CircuitSection from "./CircuitSection.js";
import type Subcircuit from "./Subcircuit.js";
import type { EventedMixin } from "../../core/Evented.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { CircuitStatus, CircuitType } from "./typeUtils.js";
import type { CircuitLocationProperties } from "./CircuitLocation.js";
import type { SubcircuitProperties } from "./Subcircuit.js";

export type CommonProperties = Pick<Circuit, "name">
  & Partial<Pick<Circuit, "attributes" | "circuitManager" | "circuitType" | "globalId" | "subcircuits">>;

export interface EmptyCircuitProperties extends CommonProperties {
  startLocation?: null;
  stopLocation?: null;
  sections?: null;
}

export interface NonSectionedCircuitProperties extends CommonProperties {
  startLocation: CircuitLocation;
  stopLocation: CircuitLocation;
  sections?: null;
}

export interface SectionedCircuitProperties extends CommonProperties {
  startLocation?: null;
  stopLocation?: null;
  sections: Map<CircuitSection, CircuitSection[]>;
}

export interface CircuitEvents {}

/**
 * Represents a circuit in a telecom domain network.
 *
 * ## Creating a Circuit
 *
 * Circuits may be created in one of three ways: with [start location](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#startLocation) and [stop location](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#stopLocation),
 * with [sections](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#sections), or with neither.
 *
 * Keep in mind that [name](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#name) must always be specified when instantiating a Circuit, and the following may be
 * optionally specified: [attributes](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#attributes), [circuitManager](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#circuitManager), [circuitType](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#circuitType),
 * and [subcircuits](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#subcircuits).
 *
 * <details>
 * <summary>Read More</summary>
 *
 * ### With start and stop location
 *
 * If created with start and stop [locations](https://developers.arcgis.com/javascript/latest/references/core/networks/support/CircuitLocation/), [isSectioned](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#isSectioned) is false.
 *
 * ```ts
 * const startLocation = new CircuitLocation({
 *   sourceId: 20,
 *   globalId: "{665803BB-258E-4BAE-A5B2-27DBD8A83C30}",
 *   firstUnit: 1,
 *   lastUnit: 1,
 * });
 *
 * const stopLocation = new CircuitLocation({
 *   sourceId: 20,
 *   globalId: "{58CB492A-1992-4518-A60F-6119B1317E89}",
 *   firstUnit: 1,
 *   lastUnit: 1,
 * });
 *
 * const circuit = new Circuit({
 *   name: "FIRSTCIRCUIT",
 *   circuitType: "physical",
 *   startLocation,
 *   stopLocation,
 * });
 * ```
 *
 * ### With sections
 *
 * If created with [sections](https://developers.arcgis.com/javascript/latest/references/core/networks/support/CircuitSection/), [isSectioned](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#isSectioned) is true.
 *
 * ```ts
 * const sectionOne = new CircuitSection({
 *   sectionId: 1,
 *   subcircuit: new Subcircuit({ name: "SUBCIRCUITVALUE1" }),
 * });
 *
 * const sectionTwo = new CircuitSection({
 *   sectionId: 2,
 *   subcircuit: new Subcircuit({ name: "SUBCIRCUITVALUE2" }),
 * });
 *
 * const sectionThree = new CircuitSection({
 *   sectionId: 3,
 *   subcircuit: new Subcircuit({ name: "SUBCIRCUITVALUE3" }),
 * });
 *
 * const sectionFour = new CircuitSection({
 *   sectionId: 4,
 *   subcircuit: new Subcircuit({ name: "SUBCIRCUITVALUE4" }),
 * });
 *
 * const sections = new Map([
 *   [sectionOne, [sectionTwo, sectionThree]],
 *   [sectionTwo, [sectionFour]],
 *   [sectionThree, [sectionFour]],
 *   [sectionFour, []],
 * ]);
 *
 * const circuit = new Circuit({
 *   name: "TESTCIRCUIT",
 *   sections,
 * });
 * ```
 *
 * ### As an empty circuit
 *
 * It is possible to create an empty circuit, without start locations, stop locations, or sections. In this scenario,
 * [isSectioned](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Circuit/#isSectioned) will be false until locations or sections are added to the Circuit.
 *
 * ```ts
 * const circuit = new Circuit({ name: "TESTCIRCUIT" });
 * ```
 *
 * </details>
 *
 * @beta
 * @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 [CircuitSection](https://developers.arcgis.com/javascript/latest/references/core/networks/support/CircuitSection/)
 * @see [Subcircuit](https://developers.arcgis.com/javascript/latest/references/core/networks/support/Subcircuit/)
 * @see [CircuitLocation](https://developers.arcgis.com/javascript/latest/references/core/networks/support/CircuitLocation/)
 * @see [Telecom domain network](https://pro.arcgis.com/en/pro-app/latest/help/data/utility-network/telecom-domain-networks.htm)
 */
export default class Circuit extends CircuitSuperclass {
  /**
   * @deprecated
   * Do not directly reference this property.
   * Use EventNames and EventTypes helpers from \@arcgis/core/Evented
   */
  "@eventTypes": CircuitEvents;
  constructor(circuitProperties?: Circuit | NonSectionedCircuitProperties | SectionedCircuitProperties | EmptyCircuitProperties);
  /** User-defined attributes on the circuit. */
  accessor attributes: Record<string, any> | null | undefined;
  /**
   * An instance of `CircuitManager` associated with the circuit.
   *
   * This is updated when a circuit is successfully created or altered with
   * `CircuitManager.create()` or `CircuitManager.alter()`.
   */
  accessor circuitManager: CircuitManager | null | undefined;
  /**
   * Indicates the type of the circuit.
   *
   * A virtual circuit does not require traversability between its start and stop locations.
   * If a virtual circuit is also a sectioned circuit, the circuit must have at least one virtual section.
   *
   * @default "physical"
   */
  accessor circuitType: CircuitType;
  /** The global ID of the circuit. */
  accessor globalId: string | null | undefined;
  /** Whether the circuit has been logically deleted. */
  get isDeleted(): boolean;
  /** Whether the circuit is defined by circuit sections. */
  get isSectioned(): boolean;
  /** The last time the circuit was exported. */
  get lastExportedTime(): Date | null | undefined;
  /** The last time the circuit was verified. */
  get lastVerifiedTime(): Date | null | undefined;
  /**
   * The name of the circuit.
   * This name is unique within the domain network.
   */
  accessor name: string;
  /**
   * A map representing the logical connectivity between circuit sections as a directed adjacency list.
   * Each key is a [CircuitSection](https://developers.arcgis.com/javascript/latest/references/core/networks/support/CircuitSection/) that connects to the other
   * [CircuitSection](https://developers.arcgis.com/javascript/latest/references/core/networks/support/CircuitSection/) instances indicated by the key's value.
   *
   * For example, consider the following keys and values, where each number is a section ID:
   *
   * ```json
   * {
   *   "1": [2, 3],
   *   "2": [4],
   *   "3": [4],
   *   "4": [],
   * }
   * ```
   *
   * In this example, section 1 connects to 2 and 3 (where sections 2 and 3 are in parallel), 2 connects to 4,
   * 3 connects to 4, and 4 connects to nothing (is the end of the circuit).
   *
   * This connectivity between sections is graphically represented as:
   *
   * ```
   *   1
   *  / \
   * 2   3
   *  \ /
   *   4
   * ```
   *
   * @example
   * const sectionOne = new CircuitSection({
   *   sectionId: 1,
   *   subcircuit: new Subcircuit({ name: "SUBCIRCUITVALUE1" }),
   * });
   *
   * const sectionTwo = new CircuitSection({
   *   sectionId: 2,
   *   subcircuit: new Subcircuit({ name: "SUBCIRCUITVALUE2" }),
   * });
   *
   * const sectionThree = new CircuitSection({
   *   sectionId: 3,
   *   subcircuit: new Subcircuit({ name: "SUBCIRCUITVALUE3" }),
   * });
   *
   * const sectionFour = new CircuitSection({
   *   sectionId: 4,
   *   subcircuit: new Subcircuit({ name: "SUBCIRCUITVALUE4" }),
   * });
   *
   * const sections = new Map([
   *   [sectionOne, [sectionTwo, sectionThree]],
   *   [sectionTwo, [sectionFour]],
   *   [sectionThree, [sectionFour]],
   *   [sectionFour, []],
   * ]);
   *
   * const circuit = new Circuit({
   *   name: "TESTCIRCUIT",
   *   sections,
   * });
   */
  accessor sections: Map<CircuitSection, CircuitSection[]> | null | undefined;
  /**
   * The feature or object associated with the start location of the circuit.
   * This property is null if the circuit is sectioned.
   */
  get startLocation(): CircuitLocation | null | undefined;
  set startLocation(value: CircuitLocationProperties | null | undefined);
  /**
   * Indicates the status of the circuit.
   *
   * The circuit status is initially "dirty" and remains dirty until the circuit is validated.
   * The circuit status is "clean" when the circuit has been successfully validated.
   * The circuit status returns to "dirty" if any circuit components are modified.
   */
  get status(): CircuitStatus;
  /**
   * The feature or object associated with the stop location of the circuit.
   * This property is null if the circuit is sectioned.
   */
  get stopLocation(): CircuitLocation | null | undefined;
  set stopLocation(value: CircuitLocationProperties | null | undefined);
  /** The subcircuits that the circuit is subdivided into. */
  get subcircuits(): Subcircuit[];
  set subcircuits(value: SubcircuitProperties[]);
  /**
   * Returns the value of the specified user-defined attribute.
   *
   * @param name - The name of the attribute.
   * @returns Returns the value of the attribute specified by `name`.
   */
  getAttribute<T = any>(name: string): T;
  /**
   * Returns the [CircuitSection](https://developers.arcgis.com/javascript/latest/references/core/networks/support/CircuitSection/) instance with a specified section ID
   * from the circuit's `sections`.
   *
   * @param sectionId - The section ID of the section to retrieve.
   * @returns The circuit section with the specified ID, if one exists in the circuit.
   */
  getSectionById(sectionId: number): CircuitSection | null;
  /**
   * Sets a new value for the specified user-defined attribute.
   *
   * @param name - The name of the attribute to set.
   * @param newValue - The new value to set on the named attribute.
   */
  setAttribute(name: string, newValue: any): void;
  /**
   * Sets the sections of the circuit.
   * This method sets the circuit's `startLocation` and `stopLocation` to null, making this a sectioned circuit.
   *
   * @param sections - The circuit's sections.
   */
  setSections(sections: Map<CircuitSection, CircuitSection[]>): void;
  /**
   * Sets the start and stop locations of the circuit.
   * This method sets the circuit's `sections` to null, making this a non-sectioned circuit.
   *
   * @param startLocation - The start location of the circuit.
   * @param stopLocation - The stop location of the circuit.
   */
  setStartStopLocations(startLocation: CircuitLocation, stopLocation: CircuitLocation): void;
}
declare const CircuitSuperclass: typeof JSONSupport & typeof EventedMixin