<?php
/**
 * getmer.ajax.php - AJAX endpoint for fetching Meraki switch information
 * 
 * This script handles AJAX requests to fetch Meraki switch information using the API.
 * It processes POST requests with a meraki_api_key parameter and returns JSON responses.
 * 
 * Expected POST parameters:
 * - meraki_api_key: 40-character Meraki API key
 * 
 * Returns JSON response with either:
 * - Success: Array of switch objects with SNMP information
 * - Error: Object with 'error' key containing error message
 */

// Set content type to JSON
header('Content-Type: application/json');

// Only allow POST requests
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'Method not allowed. Only POST requests are supported.']);
    exit;
}

// Get the API key from POST data
$api_key = isset($_POST['meraki_api_key']) ? trim($_POST['meraki_api_key']) : '';

// Validate API key
if (empty($api_key)) {
    http_response_code(400);
    echo json_encode(['error' => 'Meraki API key is required.']);
    exit;
}

if (strlen($api_key) !== 40) {
    http_response_code(400);
    echo json_encode(['error' => 'Meraki API key must be exactly 40 characters.']);
    exit;
}

// Validate API key format (alphanumeric)
if (!preg_match('/^[a-zA-Z0-9]{40}$/', $api_key)) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid API key format. Must be 40 alphanumeric characters.']);
    exit;
}

/**
 * Fetches information from Meraki API for switches in the organization
 * 
 * @param string $api_key The 40 character Meraki API key
 * @return array Array of switch devices with their details and SNMP info, or error array
 */
function fetch_meraki_switch_info($api_key) {
    $result = array();
    
    // Set up curl options for all requests
    $curl_opts = array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_HTTPHEADER => array(
            'Authorization: Bearer ' . $api_key,
            'Content-Type: application/json',
            'User-Agent: NagiosXI-Switch-Wizard/1.0'
        ),
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS => 3
    );
    
    // Get organizations
    $ch = curl_init('https://api.meraki.com/api/v1/organizations');
    curl_setopt_array($ch, $curl_opts);
    $orgs_response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curl_error = curl_error($ch);
    curl_close($ch);
    
    if ($curl_error) {
        return array('error' => 'Connection error: ' . $curl_error);
    }
    
    if ($http_code == 401) {
        return array('error' => 'Authentication failed. Please check your API key.');
    }
    
    if ($http_code == 403) {
        return array('error' => 'Access forbidden. Please check your API key permissions.');
    }
    
    if ($http_code != 200) {
        return array('error' => 'Failed to fetch organizations. HTTP code: ' . $http_code);
    }
    
    $orgs = json_decode($orgs_response, true);
    if (!is_array($orgs) || empty($orgs)) {
        return array('error' => 'No organizations found or invalid API response');
    }
    
    // Process each organization
    foreach ($orgs as $org) {
        $org_id = $org['id'];
        
        // Get devices for this organization
        $ch = curl_init("https://api.meraki.com/api/v1/organizations/{$org_id}/devices");
        curl_setopt_array($ch, $curl_opts);
        $devices_response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curl_error = curl_error($ch);
        curl_close($ch);
        
        if ($curl_error || $http_code != 200) {
            continue; // Skip this organization if we can't get devices
        }
        
        $devices = json_decode($devices_response, true);
        if (!is_array($devices)) {
            continue;
        }
        
        // Filter for switches and collect their information
        foreach ($devices as $device) {
            if (isset($device['productType']) && $device['productType'] == 'switch') {
                $switch_info = array(
                    'name' => !empty($device['name']) ? $device['name'] : (!empty($device['lanIp']) ? $device['lanIp'] : $device['serial']),
                    'serial' => isset($device['serial']) ? $device['serial'] : '',
                    'mac' => isset($device['mac']) ? $device['mac'] : '',
                    'networkId' => isset($device['networkId']) ? $device['networkId'] : '',
                    'lanIp' => isset($device['lanIp']) ? $device['lanIp'] : '',
                    'model' => isset($device['model']) ? $device['model'] : '',
                    'snmpversion' => '2c', // Default to 2c, will be updated based on access type
                    'snmpopts' => array(
                        'snmpcommunity' => 'public',
                        'v3_security_level' => '',
                        'v3_username' => '',
                        'v3_auth_password' => '',
                        'v3_priv_password' => '',
                        'v3_auth_proto' => '',
                        'v3_priv_proto' => ''
                    )
                );
                
                // Get SNMP settings for this network
                if (!empty($device['networkId'])) {
                    $ch = curl_init("https://api.meraki.com/api/v1/networks/{$device['networkId']}/snmp");
                    curl_setopt_array($ch, $curl_opts);
                    $snmp_response = curl_exec($ch);
                    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                    $curl_error = curl_error($ch);
                    curl_close($ch);
                    
                    if (!$curl_error && $http_code == 200) {
                        $snmp_settings = json_decode($snmp_response, true);
                        if (is_array($snmp_settings)) {
                            // Map Meraki SNMP settings to our snmpopts format
                            
                            // Check for access type and set snmpversion accordingly
                            if (isset($snmp_settings['access'])) {
                                if ($snmp_settings['access'] === 'community') {
                                    // Set version to 2c for community access
                                    $switch_info['snmpversion'] = '2c';
                                    
                                    // Copy community string if available
                                    if (isset($snmp_settings['communityString']) && !empty($snmp_settings['communityString'])) {
                                        $switch_info['snmpopts']['snmpcommunity'] = $snmp_settings['communityString'];
                                    }
                                } elseif ($snmp_settings['access'] === 'users') {
                                    // Set version to 3 for users access
                                    $switch_info['snmpversion'] = '3';
                                    
                                    // Set default protocols for users access
                                    $switch_info['snmpopts']['v3_auth_proto'] = 'SHA';
                                    $switch_info['snmpopts']['v3_priv_proto'] = 'AES';
                                    
                                    // Handle users array
                                    if (isset($snmp_settings['users']) && is_array($snmp_settings['users'])) {
                                        // Get the first user (or you could iterate through all users)
                                        $first_user = reset($snmp_settings['users']);
                                        if (is_array($first_user)) {
                                            // Copy username
                                            if (isset($first_user['username']) && !empty($first_user['username'])) {
                                                $switch_info['snmpopts']['v3_username'] = $first_user['username'];
                                            }
                                            
                                            // Copy passphrase to both auth and priv password fields
                                            if (isset($first_user['passphrase']) && !empty($first_user['passphrase'])) {
                                                $switch_info['snmpopts']['v3_auth_password'] = $first_user['passphrase'];
                                                $switch_info['snmpopts']['v3_priv_password'] = $first_user['passphrase'];
                                            }
                                        }
                                    }
                                }
                            }
                            
                            // SNMP v2c settings (legacy/additional check for backward compatibility)
                            if (isset($snmp_settings['v2cEnabled']) && $snmp_settings['v2cEnabled'] && 
                                isset($snmp_settings['communityString']) && !empty($snmp_settings['communityString'])) {
                                $switch_info['snmpopts']['snmpcommunity'] = $snmp_settings['communityString'];
                                // Only set version if not already set by access type
                                if (!isset($snmp_settings['access'])) {
                                    $switch_info['snmpversion'] = '2c';
                                }
                            }
                            
                            // SNMP v3 settings (legacy/additional check for backward compatibility)
                            if (isset($snmp_settings['v3Enabled']) && $snmp_settings['v3Enabled']) {
                                // Only set version if not already set by access type
                                if (!isset($snmp_settings['access'])) {
                                    $switch_info['snmpversion'] = '3';
                                }
                                
                                if (isset($snmp_settings['v3AuthMode']) && !empty($snmp_settings['v3AuthMode'])) {
                                    $switch_info['snmpopts']['v3_security_level'] = $snmp_settings['v3AuthMode'];
                                }
                                if (isset($snmp_settings['v3AuthPass']) && !empty($snmp_settings['v3AuthPass'])) {
                                    $switch_info['snmpopts']['v3_auth_password'] = $snmp_settings['v3AuthPass'];
                                }
                                if (isset($snmp_settings['v3PrivPass']) && !empty($snmp_settings['v3PrivPass'])) {
                                    $switch_info['snmpopts']['v3_priv_password'] = $snmp_settings['v3PrivPass'];
                                }
                                if (isset($snmp_settings['v3AuthProtocol']) && !empty($snmp_settings['v3AuthProtocol'])) {
                                    $switch_info['snmpopts']['v3_auth_proto'] = strtoupper($snmp_settings['v3AuthProtocol']);
                                }
                                if (isset($snmp_settings['v3PrivProtocol']) && !empty($snmp_settings['v3PrivProtocol'])) {
                                    $switch_info['snmpopts']['v3_priv_proto'] = strtoupper($snmp_settings['v3PrivProtocol']);
                                }
                                if (isset($snmp_settings['v3Username']) && !empty($snmp_settings['v3Username'])) {
                                    $switch_info['snmpopts']['v3_username'] = $snmp_settings['v3Username'];
                                }
                            }
                            
                            // Store raw SNMP settings for debugging/reference
                            $switch_info['raw_snmp_settings'] = $snmp_settings;
                        }
                    }
                }
                
                $result[] = $switch_info;
            }
        }
    }
    
    return $result;
}

// Execute the function and return results
try {
    $switches = fetch_meraki_switch_info($api_key);
    
    if (isset($switches['error'])) {
        // Error case
        http_response_code(400);
        echo json_encode($switches);
    } else {
        // Success case
        echo json_encode($switches);
    }
} catch (Exception $e) {
    // Catch any unexpected errors
    http_response_code(500);
    echo json_encode(['error' => 'Internal server error: ' . $e->getMessage()]);
}