#!/usr/bin/env node
/**
 * Android Device Detection Module
 * Detects Android devices connected via USB and wireless
 * Compatible with iOS device detection module
 */

const { exec, execSync } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);

/**
 * Detect USB-connected Android devices
 * @returns {Promise<Array>} List of detected devices
 */
async function detectUSBDevices() {
  try {
    const { stdout } = await execAsync('adb devices -l');
    const lines = stdout.split('\n').slice(1); // Skip header
    
    const devices = [];
    
    for (const line of lines) {
      if (!line.trim() || !line.includes('device')) continue;
      
      const parts = line.trim().split(/\s+/);
      const serial = parts[0];
      const status = parts[1];
      
      if (status !== 'device') continue;
      
      // Skip wireless devices (they have :PORT in serial)
      if (serial.includes(':')) continue;
      
      // Get device model
      let model = 'Unknown';
      const modelMatch = line.match(/model:([^\s]+)/);
      if (modelMatch) {
        model = modelMatch[1].replace(/_/g, ' ');
      } else {
        try {
          const { stdout: modelStdout } = await execAsync(`adb -s ${serial} shell getprop ro.product.model`);
          model = modelStdout.trim().replace(/\r/g, '');
        } catch (err) {
          // Ignore error, use Unknown
        }
      }
      
      // Get Android version
      let androidVersion = '';
      try {
        const { stdout: versionStdout } = await execAsync(`adb -s ${serial} shell getprop ro.build.version.release`);
        androidVersion = versionStdout.trim().replace(/\r/g, '');
      } catch (err) {
        // Ignore
      }
      
      devices.push({
        name: model,
        udid: serial,
        serial: serial,
        ip: '',
        platform: 'android',
        connectionType: 'usb',
        type: 'usb',
        osVersion: androidVersion,
        status: 'connected'
      });
    }
    
    return devices;
  } catch (error) {
    console.error('Error detecting USB Android devices:', error.message);
    return [];
  }
}

/**
 * Detect wireless Android devices
 * @returns {Promise<Array>} List of detected wireless devices
 */
async function detectWirelessDevices() {
  try {
    const { stdout } = await execAsync('adb devices -l');
    const lines = stdout.split('\n').slice(1);
    
    const devices = [];
    
    for (const line of lines) {
      if (!line.trim() || !line.includes('device')) continue;
      if (!line.includes(':5555')) continue; // Wireless connections typically use port 5555
      
      const parts = line.trim().split(/\s+/);
      const address = parts[0]; // IP:PORT
      const status = parts[1];
      
      if (status !== 'device') continue;
      
      const [ip, port] = address.split(':');
      
      // Get device info
      let model = 'Unknown';
      try {
        const { stdout: modelStdout } = await execAsync(`adb -s ${address} shell getprop ro.product.model`);
        model = modelStdout.trim().replace(/\r/g, '');
      } catch (err) {
        // Ignore
      }
      
      let serial = address;
      try {
        const { stdout: serialStdout } = await execAsync(`adb -s ${address} shell getprop ro.serialno`);
        const actualSerial = serialStdout.trim().replace(/\r/g, '');
        if (actualSerial && actualSerial !== 'unknown') {
          serial = actualSerial;
        }
      } catch (err) {
        // Keep using IP:PORT as serial
      }
      
      let androidVersion = '';
      try {
        const { stdout: versionStdout } = await execAsync(`adb -s ${address} shell getprop ro.build.version.release`);
        androidVersion = versionStdout.trim().replace(/\r/g, '');
      } catch (err) {
        // Ignore
      }
      
      devices.push({
        name: model,
        udid: address, // For wireless, UDID is IP:PORT
        serial: serial,
        ip: ip,
        platform: 'android',
        connectionType: 'wireless',
        type: 'wireless',
        osVersion: androidVersion,
        status: 'connected'
      });
    }
    
    return devices;
  } catch (error) {
    console.error('Error detecting wireless Android devices:', error.message);
    return [];
  }
}

/**
 * Detect all Android devices (USB + Wireless)
 * @returns {Promise<Array>} Combined list of all detected devices
 */
async function discoverAllAndroidDevices() {
  try {
    // Check if ADB is available
    try {
      execSync('which adb', { stdio: 'ignore' });
    } catch (err) {
      console.warn('ADB not found. Please install Android SDK Platform Tools.');
      return [];
    }
    
    const [usbDevices, wirelessDevices] = await Promise.all([
      detectUSBDevices(),
      detectWirelessDevices()
    ]);
    
    // Combine and deduplicate by serial
    const allDevices = [...usbDevices, ...wirelessDevices];
    const uniqueDevices = [];
    const seenSerials = new Set();
    
    for (const device of allDevices) {
      if (!seenSerials.has(device.serial)) {
        seenSerials.add(device.serial);
        uniqueDevices.push(device);
      }
    }
    
    return uniqueDevices;
  } catch (error) {
    console.error('Error discovering Android devices:', error.message);
    return [];
  }
}

/**
 * Get device battery level
 * @param {string} serial - Device serial number
 * @returns {Promise<number>} Battery level percentage
 */
async function getDeviceBattery(serial) {
  try {
    const { stdout } = await execAsync(`adb -s ${serial} shell dumpsys battery`);
    const levelMatch = stdout.match(/level:\s*(\d+)/);
    return levelMatch ? parseInt(levelMatch[1]) : -1;
  } catch (error) {
    return -1;
  }
}

/**
 * Check if UIAutomator2 server is installed
 * @param {string} serial - Device serial number
 * @returns {Promise<boolean>} True if installed
 */
async function isUIAutomator2Installed(serial) {
  try {
    const { stdout } = await execAsync(`adb -s ${serial} shell pm list packages`);
    return stdout.includes('io.appium.uiautomator2.server');
  } catch (error) {
    return false;
  }
}

/**
 * Get list of installed apps (non-system)
 * @param {string} serial - Device serial number
 * @returns {Promise<Array>} List of package names
 */
async function getInstalledApps(serial) {
  try {
    const { stdout } = await execAsync(`adb -s ${serial} shell pm list packages -3`);
    return stdout.split('\n')
      .filter(line => line.trim())
      .map(line => line.replace('package:', '').trim());
  } catch (error) {
    return [];
  }
}

// Export functions
module.exports = {
  detectUSBDevices,
  detectWirelessDevices,
  discoverAllAndroidDevices,
  getDeviceBattery,
  isUIAutomator2Installed,
  getInstalledApps
};

// CLI mode
if (require.main === module) {
  (async () => {
    console.log('🤖 Detecting Android devices...\n');
    
    const devices = await discoverAllAndroidDevices();
    
    if (devices.length === 0) {
      console.log('No Android devices detected.');
      console.log('\nMake sure:');
      console.log('  1. Device is connected via USB or wirelessly');
      console.log('  2. USB debugging is enabled');
      console.log('  3. Device is authorized (check device screen)');
      console.log('  4. ADB is properly installed');
      process.exit(1);
    }
    
    console.log(`Found ${devices.length} device(s):\n`);
    
    for (const device of devices) {
      console.log(`📱 ${device.name}`);
      console.log(`   Serial: ${device.serial}`);
      console.log(`   Android: ${device.androidVersion}`);
      console.log(`   Connection: ${device.connectionType.toUpperCase()}`);
      if (device.ip) console.log(`   IP: ${device.ip}`);
      
      const battery = await getDeviceBattery(device.serial);
      if (battery >= 0) console.log(`   Battery: ${battery}%`);
      
      const hasUI2 = await isUIAutomator2Installed(device.serial);
      console.log(`   UIAutomator2: ${hasUI2 ? '✓ Installed' : '✗ Not installed'}`);
      
      console.log('');
    }
  })();
}
