<?php
/*
 * LibreNMS entity-physical module for the discovery of components in the Ciena Service Delivery Switch family
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.  Please see LICENSE.txt at the top level of
 * the source code distribution for details.
 */

echo "\nCaching OIDs:";

$entity_array = [];

echo 'Ciena SDS';

// Chassis stuff
$chassis_array = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesChassisGlobal',
    [],
    'CIENA-CES-CHASSIS-MIB',
);
$chassis_array = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesChassisPlatform',
    $chassis_array,
    'CIENA-CES-CHASSIS-MIB',
);
$chassis_array = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesChassisIDP',
    $chassis_array,
    'CIENA-CES-CHASSIS-MIB',
);

// PSU Stuff
$cienaCesChassisPowerModule = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesChassisPowerModule',
    [],
    'CIENA-CES-CHASSIS-MIB',
);

// Fan Stuff
$cienaCesChassisFanTrayEntry = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesChassisFanTrayEntry',
    [],
    'CIENA-CES-CHASSIS-MIB',
);
$cienaCesChassisFanEntry = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesChassisFanEntry',
    [],
    'CIENA-CES-CHASSIS-MIB',
);
$cienaCesChassisFanTempEntry = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesChassisFanTempEntry',
    [],
    'CIENA-CES-CHASSIS-MIB',
);

// Module Stuff
$module_array = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesModuleEntry',
    [],
    'CIENA-CES-MODULE-MIB',
);
$module_array = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesModuleDescriptionEntry',
    $module_array,
    'CIENA-CES-MODULE-MIB',
);
$module_array = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesModuleSwEntry',
    $module_array,
    'CIENA-CES-MODULE-MIB',
);

// Interface stuff
$interfaceIndexMapping = snmpwalk_cache_multi_oid(
    $device,
    'dot1dBasePortIfIndex',
    [],
    'BRIDGE-MIB',
);

$cienaCesEttpConfigEntry = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesEttpConfigEntry',
    [],
    'CIENA-CES-PORT-MIB',
);
$cienaCesPortXcvrEntry = snmpwalk_cache_multi_oid(
    $device,
    'cienaCesPortXcvrEntry',
    [],
    'CIENA-CES-PORT-XCVR-MIB',
);

foreach ($chassis_array as $cienaCesChassis => $chassis_contents) {
    // as far as I know, there can only be 1 chassis, but iterate just in case
    $chassisIndex = $cienaCesChassis + 1;
    $entity_array[] = [
        'entPhysicalIndex'        => $chassisIndex,
        'entPhysicalDescr'        => $chassis_contents['cienaCesChassisPlatformDesc'],
        'entPhysicalClass'        => 'chassis',
        'entPhysicalName'         => 'Chassis',
        'entPhysicalModelName'    => $chassis_contents['cienaCesChassisPartNumber'],
        'entPhysicalSerialNum'    => $chassis_contents['cienaCesChassisSerialNumber'],
        'entPhysicalContainedIn'  => '0',
        'entPhysicalMfgName'      => 'Ciena',
        'entPhysicalParentRelPos' => '-1',
        'entPhysicalHardwareRev'  => $chassis_contents['cienaCesChassisIDPModelRevision'],
        'entPhysicalIsFRU'        => 'true',
    ];
    $entity_array[] = [
        'entPhysicalIndex'        => "40$chassisIndex",
        'entPhysicalClass'        => 'container',
        'entPhysicalName'         => 'Modules',
        'entPhysicalContainedIn'  => $chassisIndex,
        'entPhysicalParentRelPos' => -1,
    ];
    $entity_array[] = [
        'entPhysicalIndex'        => "41$chassisIndex",
        'entPhysicalClass'        => 'container',
        'entPhysicalName'         => 'Power Supplies',
        'entPhysicalContainedIn'  => $chassisIndex,
        'entPhysicalParentRelPos' => -1,
    ];
    $entity_array[] = [
        'entPhysicalIndex'        => "42$chassisIndex",
        'entPhysicalClass'        => 'container',
        'entPhysicalName'         => 'Fans',
        'entPhysicalContainedIn'  => $chassisIndex,
        'entPhysicalParentRelPos' => -1,
    ];
}

foreach ($cienaCesChassisPowerModule as $index => $contents) {
    $entity_array[] = [
        'entPhysicalIndex'        => "50$index",
        'entPhysicalDescr'        => $contents['cienaCesChassisPowerSupplyManufacturer'],
        'entPhysicalClass'        => 'sensor',
        'entPhysicalName'         => $contents['cienaCesChassisPowerSupplySlotName'],
        'entPhysicalModelName'    => $contents['cienaCesChassisPowerSupplyPartNum'],
        'entPhysicalSerialNum'    => $contents['cienaCesChassisPowerSupplySerialNumber'],
        'entPhysicalContainedIn'  => '41' . $contents['cienaCesChassisPowerSupplyChassisIndx'],
        'entPhysicalMfgName'      => 'Ciena',
        'entPhysicalParentRelPos' => $contents['cienaCesChassisPowerSupplySlotIndx'],
        'entPhysicalHardwareRev'  => $contents['cienaCesChassisPowerSupplyRevInfo'],
        'entPhysicalIsFRU'        => $contents['cienaCesChassisPowerSupplyFRU'],
        'ifIndex'                 => null,
    ];
}

foreach ($cienaCesChassisFanTrayEntry as $index => $contents) {
    switch ($contents['cienaCesChassisFanTrayType']) {
        case 1:
            $typeString = 'Fixed fan tray, ';
            break;
        case 2:
            $typeString = 'Hot swappable fan tray, ';
            break;
        case 3:
            $typeString = 'Unequipped fan tray, ';
            break;
        default:
            $typeString = '';
    }
    switch ($contents['cienaCesChassisFanTrayMode']) {
        case 1:
            $modeString = 'Invalid fan configuration!';
            break;
        case 2:
            $modeString = 'Fully populated';
            break;
        case 3:
            $modeString = 'Auto mode';
            break;
        default:
            $modeString = '';
    }

    $entity_array[] = [
        'entPhysicalIndex'        => "53$index",
        'entPhysicalClass'        => 'sensor',
        'entPhysicalName'         => $contents['cienaCesChassisFanTrayName'],
        'entPhysicalModelName'    => 'Fan Tray',
        'entPhysicalDescr'        => "$typeString$modeString",
        'entPhysicalSerialNum'    => $contents['cienaCesChassisFanTraySerialNumber'],
        'entPhysicalContainedIn'  => '42' . $contents['cienaCesChassisFanTrayChassisIndx'],
        'entPhysicalMfgName'      => 'Ciena',
        'entPhysicalParentRelPos' => $contents['cienaCesChassisFanTraySlotIndx'],
        'entPhysicalIsFRU'        => ($contents['cienaCesChassisFanTrayType'] = '2') ? 'true' : 'false',
    ];
}

foreach ($cienaCesChassisFanEntry as $index => $contents) {
    // index = fanTray.fanIndex
    $indexArr = explode('.', $index);
    $fanTray = $indexArr[0];
    $fanIndex = $indexArr[1];

    $entity_array[] = [
        'entPhysicalIndex'        => "51$fanIndex",
        'entPhysicalClass'        => 'sensor',
        'entPhysicalName'         => $contents['cienaCesChassisFanName'],
        'entPhysicalModelName'    => 'Fan',
        'entPhysicalContainedIn'  => (isset($cienaCesChassisFanTrayEntry[$fanTray])) ?
            "53$fanTray" : '42' . $contents['cienaCesChassisFanChassisIndx'],
        'entPhysicalMfgName'      => 'Ciena',
        'entPhysicalParentRelPos' => $fanIndex,
    ];
}

foreach ($cienaCesChassisFanTempEntry as $index => $contents) {
    // index = fanTray.sensorIndex
    $indexArr = explode('.', $index);
    $fanTray = $indexArr[0];
    $sensorIndex = $indexArr[1];

    $entity_array[] = [
        'entPhysicalIndex'        => "52$sensorIndex",
        'entPhysicalClass'        => 'sensor',
        'entPhysicalName'         => $contents['cienaCesChassisFanTempName'],
        'entPhysicalModelName'    => 'Temp Sensor',
        'entPhysicalContainedIn'  => (isset($cienaCesChassisFanTrayEntry[$fanTray])) ?
            "53$fanTray" : '42' . $contents['cienaCesChassisFanTempChassisIndx'],
        'entPhysicalParentRelPos' => -1,
    ];
}

foreach ($module_array as $index => $contents) {
    // index = chassisIndex.shelfIndex.slotIndex
    $indexArr = explode('.', $index);
    $chassisIndex = $indexArr[0];
    $shelfIndex = $indexArr[1];
    $slotIndex = $indexArr[2];

    $entity_array[] = [
        'entPhysicalIndex'        => "55$slotIndex",
        'entPhysicalDescr'        => $contents['cienaCesModuleDescription'] . ', ' . $contents['cienaCesModuleSwRunningRelease'],
        'entPhysicalClass'        => 'sensor',
        'entPhysicalName'         => $contents['cienaCesModuleSlotName'] . ': ' . $contents['cienaCesModuleDescriptionBoardName'],
        'entPhysicalModelName'    => $contents['cienaCesModuleDescriptionBoardPartNum'],
        'entPhysicalSerialNum'    => $contents['cienaCesModuleDescriptionBoardSerialNum'],
        'entPhysicalContainedIn'  => '40' . $chassisIndex,
        'entPhysicalMfgName'      => 'Ciena',
        'entPhysicalParentRelPos' => $slotIndex,
        'entPhysicalFirmwareRev'  => $contents['cienaCesModuleSwRunningRelease'],
        'entPhysicalIsFRU'        => 'true',
    ];
}

foreach ($cienaCesEttpConfigEntry as $index => $contents) {
    $portIndex = $interfaceIndexMapping[$index]['dot1dBasePortIfIndex'];
    $nameArr = explode('/', $contents['cienaCesEttpConfigName']);
    $slotIndex = ((isset($nameArr[1])) ? $nameArr[0] : 1);

    $entity_array[] = [
        'entPhysicalIndex'        => "56$index",
        'entPhysicalDescr'        => $contents['cienaCesEttpConfigEttpType'],
        'entPhysicalClass'        => 'port',
        'entPhysicalName'         => $contents['cienaCesEttpConfigName'],
        'entPhysicalContainedIn'  => '55' . $slotIndex,
        'entPhysicalParentRelPos' => $index,
        'ifIndex'                 => $portIndex,
    ];
    if (isset($cienaCesPortXcvrEntry[$index])) {
        if ($cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrOperState'] != 'notPresent') {
            $wavelengthString = ($cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrWaveLength'] != 0 ?
                $cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrWaveLength'] . ' nm ' : '');
            $mfgString = ($cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrMfgDate'] != '' ?
                'manufactured ' . $cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrMfgDate'] . ' ' : '');
            $entity_array[] = [
                'entPhysicalIndex'        => $portIndex,
                'entPhysicalDescr'        => $cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrVendorName'] . ' ' . $wavelengthString .
                    $cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrIdentiferType'] . ' transceiver ' . $mfgString,
                'entPhysicalClass'        => 'sensor',
                'entPhysicalModelName'    => $cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrVendorPartNum'],
                'entPhysicalSerialNum'    => $cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrSerialNum'],
                'entPhysicalContainedIn'  => "56$index",
                'entPhysicalMfgName'      => $cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrVendorName'],
                'entPhysicalParentRelPos' => -1,
                'entPhysicalHardwareRev'  => $cienaCesPortXcvrEntry[$index]['cienaCesPortXcvrRevNum'],
                'entPhysicalIsFRU'        => 'true',
            ];
        }
    }
}

foreach ($entity_array as $entPhysicalIndex => $entry) {
    discover_entity_physical(
        $valid,
        $device,
        array_key_exists('entPhysicalIndex', $entry) ? $entry['entPhysicalIndex'] : '',
        array_key_exists('entPhysicalDescr', $entry) ? $entry['entPhysicalDescr'] : '',
        array_key_exists('entPhysicalClass', $entry) ? $entry['entPhysicalClass'] : '',
        array_key_exists('entPhysicalName', $entry) ? $entry['entPhysicalName'] : '',
        array_key_exists('entPhysicalModelName', $entry) ? $entry['entPhysicalModelName'] : '',
        array_key_exists('entPhysicalSerialNum', $entry) ? $entry['entPhysicalSerialNum'] : '',
        array_key_exists('entPhysicalContainedIn', $entry) ? $entry['entPhysicalContainedIn'] : '',
        array_key_exists('entPhysicalMfgName', $entry) ? $entry['entPhysicalMfgName'] : '',
        array_key_exists('entPhysicalParentRelPos', $entry) ? $entry['entPhysicalParentRelPos'] : '',
        array_key_exists('entPhysicalVendorType', $entry) ? $entry['entPhysicalVendorType'] : '',
        array_key_exists('entPhysicalHardwareRev', $entry) ? $entry['entPhysicalHardwareRev'] : '',
        array_key_exists('entPhysicalFirmwareRev', $entry) ? $entry['entPhysicalFirmwareRev'] : '',
        array_key_exists('entPhysicalSoftwareRev', $entry) ? $entry['entPhysicalSoftwareRev'] : '',
        array_key_exists('entPhysicalIsFRU', $entry) ? $entry['entPhysicalIsFRU'] : '',
        array_key_exists('entPhysicalAlias', $entry) ? $entry['entPhysicalAlias'] : '',
        array_key_exists('entPhysicalAssetID', $entry) ? $entry['entPhysicalAssetID'] : '',
        array_key_exists('ifIndex', $entry) ? $entry['ifIndex'] : ''
    );
}

echo "\n";
unset(
    $chassis_array,
    $cienaCesChassisPowerModule,
    $cienaCesChassisFanTrayEntry,
    $cienaCesChassisFanEntry,
    $cienaCesChassisFanTempEntry,
    $interfaceIndexMapping,
    $cienaCesEttpConfigEntry,
    $cienaCesPortXcvrEntry,
    $module_array,
    $entry,
    $entity_array
);
