/// <reference types="node" />
import { DeviceComponent } from './hardware-description';
import { RangeOptions } from 'semver';
import { Device } from './device';
export interface Firmware {
    /**
     * @example package_SOMANET-Servo-Node-1000-E-EtherCAT-Safety_8432-03_motion-drive_v4.2.0-alpha.5.zip
     */
    packageFilename: string;
    /**
     * @example v4.2.0-alpha.5
     */
    version: string;
}
export declare const firmwareIdRegExp: RegExp;
export declare const newFirmwarePackageFilenameRegExp: RegExp;
export declare const oldFirmwarePackageFilenameRegExp: RegExp;
/**
 * New firmware package filenames are described in section 4.3.3 of the "Hardware Description File Format".
 * For more details, refer to the document at: {@link https://docs.google.com/document/d/1bafY-F8qFMLd0Las8fQFF6H9PTVYFjv01bhV7owqx8E}.
 *
 * @example
 * "package_SOMANET-Servo-Node-400-EtherCAT_9501-01-4622-1_motion-drive_v4.1.0.zip"
 */
export interface NewFirmwarePackageFilename {
    /**
     * General format description: "package" refers to the zip bundles used to deliver firmware for SOMANET devices.
     */
    description: string;
    /**
     * Human-readable hardware name, e.g., "SOMANET-Servo-Node-400-EtherCAT".
     */
    hardwareName: string;
    /**
     * {@link FirmwareId}
     */
    firmwareId: string;
    /**
     * Name of the firmware (SOMANET Software).
     *
     * @example
     * "motion-drive"
     */
    firmwareName: string;
    /**
     * Version of the firmware (SOMANET Software).
     *
     * @example
     * "v4.1.0"
     */
    firmwareVersion: string;
    productId?: number;
    productVersion?: number;
    keyId?: number;
    fieldbusProtocol?: number;
}
/**
 * Documentation for old firmware package filenames is not available.
 *
 * @example
 * "package-motion-drive_ComEtherCAT-b_CoreC2X-a_Drive400-e_v4.2.1.zip"
 */
export interface OldFirmwarePackageFilename {
    description: string;
    components: DeviceComponent[];
    firmwareVersion: string;
}
/**
 * This is referred to as the Firmware ID (FWID).
 *
 * The firmware ID consists of the following components:
 * - Product ID (mandatory) – For example, 9501. Sourced from the Assembly or Device section in the `.hardware_description` file.
 * - Product Version (mandatory) – For example, 01. Sourced from the Assembly or Device section in the `.hardware_description` file.
 * - Key ID (optional) – For example, 4622. Sourced from the Device section in the `.hardware_description` file.
 * - Fieldbus Protocol (optional) – For example, 1 for EtherCAT. Sourced from the `.variant` file.
 *
 * @example
 * "9501-01-4622-1"
 */
export interface FirmwareId {
    productId: number;
    productVersion: number;
    keyId?: number;
    fieldbusProtocol?: number;
}
/**
 * Parses the FWID string and returns a {@link FirmwareId} instance.
 *
 * Special cases:
 * - For product IDs `9506`, `9507`, `9508`, `9606`, `9607`, `9608`, `9612`, and `9614`,
 *   the **CAN** fieldbus protocol is always used, regardless of whether another protocol
 *   is specified in the FWID string.
 *
 * @throws {Error} If the provided FWID does not match the expected pattern.
 */
export declare function parseFirmwareId(fwid: string): FirmwareId | void;
/**
 * The format for new firmware package filenames is detailed in the "Hardware Description File Format" document.
 */
export declare function isNewFirmwarePackageFilename(filename: string): boolean;
/**
 * Documentation for older firmware package filenames, such as "package-motion-drive_ComEtherCAT-b_CoreC2X-a_Drive400-e_v4.2.1.zip", is unavailable.
 * These package filenames consist of three hardware components (modules): Com, Core, and Drive.
 * Firmware packages with these older naming conventions are specifically built for legacy SOMANET Node devices.
 */
export declare function isOldFirmwarePackageFilename(filename: string): boolean;
/**
 * Parses a new firmware package filename and returns an instance of {@link NewFirmwarePackageFilename}.
 * Returns `undefined` if the filename does not match the new firmware package filename format.
 *
 * @throws {Error} Throws an error if the provided filename does not match the expected pattern.
 */
export declare function parseNewFirmwarePackageFilename(filename: string): NewFirmwarePackageFilename;
/**
 * Given an old firmware package filename in the format:
 * "package-motion-drive_ComEtherCAT-b_CoreC2X-a_Drive400-e_v4.2.1.zip",
 * this function extracts the hardware components and returns an array of objects.
 * Each object includes the component name, version, and an empty serial number.
 *
 * This function is useful for determining the compatibility of a firmware package with devices that use an old `stack_info.json` file,
 * which includes only hardware components but lacks a firmware ID. To check if two sets of components match and verify compatibility,
 * use the {@link deviceComponentsMatch} function.
 *
 * @throws {Error} Throws an error if the provided filename does not match the expected pattern.
 */
export declare function extractDeviceComponentsFromOldFirmwarePackageFilename(filename: string): DeviceComponent[];
/**
 * Parses an old firmware package filename and returns an instance of {@link OldFirmwarePackageFilename}.
 * Returns `undefined` if the filename does not match the old firmware package filename format.
 *
 * @throws {Error} Throws an error if the provided filename does not match the expected pattern.
 */
export declare function parseOldFirmwarePackageFilename(filename: string): OldFirmwarePackageFilename;
/**
 * Checks if a firmware package filename is compatible with a device, based on the provided FWID or a device object with a Hardware Description and optionally an Integro Variant.
 * This function helps determine whether a firmware package can be installed on a device.
 *
 * - If the device includes Stack Info, the old firmware package filename is used.
 * - If an FWID or a device with a Hardware Description is provided, the new firmware package filename is used.
 *
 * @param filename The firmware package filename (either old or new).
 * @param firmwareIdOrDevice The FWID or device object (with `hardwareDescription`, `stackInfo`, and optionally `integroVariant`) to check compatibility.
 * @returns `true` if the firmware package filename is compatible with the device; otherwise, `false`.
 * @throws {Error} Throws an error if an invalid combination is provided, such as using an old firmware package filename with an FWID.
 */
export declare function isFirmwarePackageFilenameCompatibleWithDevice(filename: string, firmwareIdOrDevice: string | Pick<Device, 'hardwareDescription' | 'stackInfo' | 'integroVariant'>): boolean;
/**
 * Extracts the Firmware ID (FWID) from either the new firmware package filename or the provided Hardware Description.
 * The optional Integro Variant is used if the Firmware ID includes the Fieldbus Protocol.
 *
 * Note: If additional options from the Integro Variant are incorporated into the FWID in the future, this code will need to be updated accordingly.
 *
 * Note: When a Hardware Description (HD) is provided, the FWID is assembled as follows:
 * - If no assembly is present in the HD, the ID, version, and key ID are taken from the device.
 * - If an assembly is present, the ID and version are taken from the assembly, while the key ID is still taken from the device.
 * - In all cases, the key ID is sourced from the device.
 *
 * @param firmwarePackageFilenameOrDevice The new firmware package filename or a device containing a Hardware Description, with an optional Integro Variant.
 * @throws {Error} If the provided filename does not match the expected pattern.
 * @returns The Firmware ID (FWID), e.g., "9501-01-4622-1".
 */
export declare function extractFirmwareId(firmwarePackageFilenameOrDevice: string | Pick<Device, 'hardwareDescription' | 'integroVariant'>): string;
/**
 * Extracts the firmware version from the given firmware package filename, whether it's in the old or new format.
 *
 * @example
 * "v4.1.0"
 *
 * @throws {Error} Throws an error if the provided filename does not match the expected pattern.
 */
export declare function extractFirmwareVersionFromFirmwarePackageFilename(filename: string): string;
/**
 * Older firmware versions for Circulo included a different build to support the Encoder Calibration feature in order to save memory.
 * Newer firmware versions now include the Encoder Calibration feature, so a separate build is no longer necessary.
 *
 * @example
 * "package_SOMANET-Servo-Node-Circulo-7-700_8502-01_motion-drive_v0.4.3-calibration.zip"
 * "v0.4.3-calibration"
 */
export declare function isCalibrationFirmware(version?: string): boolean;
/**
 * Some older firmware versions included invalid build metadata.
 * This function removes any invalid metadata from the provided version.
 */
export declare function removeInvalidBuildMetadataFromFirmwareVersion(version: string): string;
/**
 * Checks if a firmware version satisfies the given range.
 * If no options are specified, a custom one will be used.
 * Older firmware versions sometimes included invalid build metadata, which could cause the function to fail.
 * To prevent this, the function removes any invalid build metadata before performing the version check.
 */
export declare function firmwareVersionSatisfies(version: string, range: string, options?: RangeOptions): boolean;
/**
 * Determines if a firmware version falls within a specified range.
 *
 * @param version The firmware version to check.
 * @param range A version range, following the syntax outlined in {@link https://github.com/npm/node-semver#ranges}.
 * @param calibration If a string, it will be treated as a range. Otherwise, the function returns the boolean value of `calibration`.
 */
export declare function isFirmwareVersionInRange(version: string, range?: string | null, calibration?: boolean | string): boolean;
/**
 * Checks if the provided firmware version includes the new encoder configuration objects (0x2110 and 0x2112).
 * Firmware versions starting from v5.0.0-rc.5 and v0.4.0-calibration include these objects.
 *
 * Previously, firmware had separate objects for each type of encoder (sensor), resulting in more than 12 record objects,
 * each with several subitems. This consumed unnecessary memory, prompting a refactor to introduce the new encoder configuration objects.
 *
 * The new configuration is referred to as "encoder configuration" (0x2110, 0x2112), while the older is called "sensor configuration".
 */
export declare function isEncoderConfigurationFirmware(version?: string): boolean;
/**
 * Resolves a list of installable firmware versions based on the provided firmware package filenames.
 * Filters the list by the specified FWID or device, and optionally sorts the results by version in descending order.
 *
 * @param filenames An array of firmware package filenames to evaluate.
 * @param firmwareIdOrDevice The FWID or device object (with `hardwareDescription`, `stackInfo`, and optionally `integroVariant`) to check compatibility.
 * @param sortByVersion Optional flag to sort the resulting firmware list by version in descending order (default is `false`).
 * @returns A list of compatible firmware packages, each with its filename and version.
 */
export declare function resolveInstallableFirmwares(filenames: string[], firmwareIdOrDevice: string | Pick<Device, 'hardwareDescription' | 'stackInfo' | 'integroVariant'>, sortByVersion?: boolean): Firmware[];
/**
 * Parses the Integro firmware version and returns an object with the date, day, month, year, version.
 *
 * @param value The Integro firmware version.
 * @returns An object with the date, day, month, year, version.
 */
export declare function parseIntegroFirmwareVersion(value: number): {
    date: Date;
    day: string;
    month: string;
    value: number;
    version: string;
    year: string;
};
/**
 * Compares two firmware versions in descending order.
 */
export declare function compareFirmwarePackagesByVersionDesc(a: string, b: string): number;
/**
 * Maps firmware packages to filenames and buffers.
 *
 * @param packages
 * @returns
 */
export declare function mapPackagesToFilenameAndBuffer(packages: any[]): {
    filename: string;
    buffer: Buffer;
}[];
