File storage-module.js of Package PersistenceOS

/**
 * PersistenceOS Storage Management Module
 * Handles storage pools, disk operations, and storage-related functionality
 * 
 * Depends on: core-utils.js, auth-module.js
 */

// =============================================================================
// STORAGE STATE MANAGEMENT
// =============================================================================

const storageState = {
    storagePools: [],
    isLoading: false,
    refreshInterval: null,
    lastUpdate: null
};

// =============================================================================
// STORAGE DATA FUNCTIONS
// =============================================================================

/**
 * Refresh storage data from API
 * @returns {Promise<void>}
 */
async function refreshStorage() {
    storageState.isLoading = true;
    console.log('๐Ÿ”„ Refreshing storage data...');
    
    try {
        const data = await PersistenceCore.apiGet('/storage/');
        console.log('โœ… Storage data loaded:', data);
        
        // Transform API data to match UI format
        storageState.storagePools = (data.pools || []).map(pool => ({
            name: pool.name || 'Unknown',
            status: pool.status || 'unknown',
            type: pool.type || 'unknown',
            size: pool.size || '0 GB',
            used: pool.used || '0 GB',
            available: pool.available || '0 GB',
            usedPercent: pool.used_percent || 0,
            health: pool.health || 'unknown',
            mountPoint: pool.mount_point || '',
            filesystem: pool.filesystem || 'unknown'
        }));
        
        console.log(`๐Ÿ“Š Updated storage pools: ${storageState.storagePools.length} pools found`);
        
        if (storageState.storagePools.length === 0) {
            PersistenceCore.showNotification('โ„น๏ธ No storage pools found', 'info');
        } else {
            const healthyPools = storageState.storagePools.filter(p => p.status === 'healthy').length;
            PersistenceCore.showNotification(`โœ… Found ${storageState.storagePools.length} storage pools (${healthyPools} healthy)`, 'success');
        }
        
        storageState.lastUpdate = new Date();
        
        // Trigger custom event for Vue.js reactivity
        window.dispatchEvent(new CustomEvent('storage-data-updated', {
            detail: { pools: storageState.storagePools, stats: getStorageStats() }
        }));
        
    } catch (error) {
        console.error('โŒ Error refreshing storage:', error);
        PersistenceCore.showNotification('โŒ Error refreshing storage data', 'error');
    } finally {
        storageState.isLoading = false;
    }
}

/**
 * Get storage statistics
 * @returns {object}
 */
function getStorageStats() {
    const pools = storageState.storagePools;
    const healthy = pools.filter(p => p.status === 'healthy').length;
    const degraded = pools.filter(p => p.status === 'degraded').length;
    const total = pools.length;
    
    // Calculate total storage usage
    let totalSize = 0;
    let totalUsed = 0;
    
    pools.forEach(pool => {
        // Parse size strings (e.g., "100 GB" -> 100)
        const sizeMatch = pool.size.match(/(\d+(?:\.\d+)?)/);
        const usedMatch = pool.used.match(/(\d+(?:\.\d+)?)/);
        
        if (sizeMatch) totalSize += parseFloat(sizeMatch[1]);
        if (usedMatch) totalUsed += parseFloat(usedMatch[1]);
    });
    
    const overallUsage = totalSize > 0 ? Math.round((totalUsed / totalSize) * 100) : 0;
    
    return {
        total,
        healthy,
        degraded,
        totalSize: `${totalSize.toFixed(1)} GB`,
        totalUsed: `${totalUsed.toFixed(1)} GB`,
        overallUsage
    };
}

// =============================================================================
// STORAGE POOL OPERATIONS
// =============================================================================

/**
 * Create new storage pool
 * @returns {Promise<void>}
 */
async function createPool() {
    console.log('โž• Opening Create Storage Pool dialog');
    
    // Create storage pool creation modal
    const modalHtml = `
        <div id="createPoolModal" class="modal" style="display: block;">
            <div class="modal-content" style="max-width: 600px;">
                <div class="modal-header">
                    <h3><i class="fas fa-plus"></i> Create Storage Pool</h3>
                    <button class="close-btn" onclick="closeCreatePoolModal()">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
                <div class="modal-body">
                    <form id="createPoolForm">
                        <div class="form-group">
                            <label>Pool Name:</label>
                            <input type="text" id="poolName" required placeholder="Enter pool name">
                        </div>
                        <div class="form-group">
                            <label>Pool Type:</label>
                            <select id="poolType" required>
                                <option value="btrfs">BTRFS (Recommended)</option>
                                <option value="xfs">XFS</option>
                                <option value="ext4">EXT4</option>
                            </select>
                        </div>
                        <div class="form-group">
                            <label>Device/Path:</label>
                            <input type="text" id="poolDevice" required placeholder="/dev/sdb or /path/to/directory">
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button onclick="closeCreatePoolModal()" class="btn btn-secondary">Cancel</button>
                    <button onclick="submitCreatePool()" class="btn btn-primary">Create Pool</button>
                </div>
            </div>
        </div>
    `;
    
    // Add modal to DOM
    document.body.insertAdjacentHTML('beforeend', modalHtml);
    document.body.classList.add('modal-open');
    
    // Add modal functions
    window.closeCreatePoolModal = () => {
        const modal = document.getElementById('createPoolModal');
        if (modal) {
            modal.remove();
            document.body.classList.remove('modal-open');
        }
        delete window.closeCreatePoolModal;
        delete window.submitCreatePool;
    };
    
    window.submitCreatePool = async () => {
        const name = document.getElementById('poolName').value;
        const type = document.getElementById('poolType').value;
        const device = document.getElementById('poolDevice').value;
        
        if (!name || !type || !device) {
            PersistenceCore.showNotification('Please fill in all fields', 'error');
            return;
        }
        
        try {
            await PersistenceCore.apiPost('/storage/pools', {
                name,
                type,
                device
            });
            
            PersistenceCore.showNotification(`Storage pool "${name}" created successfully`, 'success');
            window.closeCreatePoolModal();
            await refreshStorage();
            
        } catch (error) {
            console.error('โŒ Failed to create storage pool:', error);
            PersistenceCore.showNotification('Failed to create storage pool', 'error');
        }
    };
}

/**
 * Import existing storage pool
 * @returns {Promise<void>}
 */
async function importPool() {
    console.log('๐Ÿ“ฅ Opening Import Storage Pool dialog');
    PersistenceCore.showNotification('๐Ÿšง Import Pool feature - In development', 'info');
    
    // TODO: Implement pool import functionality
    // - Scan for existing pools
    // - Import configuration
    // - Validate pool integrity
}

/**
 * Manage storage pool
 * @param {string} poolName - Pool name
 * @returns {Promise<void>}
 */
async function managePool(poolName) {
    console.log(`โš™๏ธ Managing storage pool: ${poolName}`);
    
    const pool = storageState.storagePools.find(p => p.name === poolName);
    if (!pool) {
        PersistenceCore.showNotification('Storage pool not found', 'error');
        return;
    }
    
    // Create pool management modal
    const modalHtml = `
        <div id="managePoolModal" class="modal" style="display: block;">
            <div class="modal-content" style="max-width: 700px;">
                <div class="modal-header">
                    <h3><i class="fas fa-cog"></i> Manage Pool - ${poolName}</h3>
                    <button class="close-btn" onclick="closeManagePoolModal()">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
                <div class="modal-body">
                    <div class="pool-info">
                        <h4>Pool Information</h4>
                        <p><strong>Name:</strong> ${pool.name}</p>
                        <p><strong>Type:</strong> ${pool.type}</p>
                        <p><strong>Status:</strong> <span class="status-${pool.status}">${pool.status}</span></p>
                        <p><strong>Size:</strong> ${pool.size}</p>
                        <p><strong>Used:</strong> ${pool.used} (${pool.usedPercent}%)</p>
                        <p><strong>Available:</strong> ${pool.available}</p>
                        <p><strong>Mount Point:</strong> ${pool.mountPoint || 'N/A'}</p>
                    </div>
                    <div class="pool-actions">
                        <h4>Actions</h4>
                        <button class="btn btn-primary" onclick="scrubPool('${poolName}')">
                            <i class="fas fa-broom"></i> Scrub Pool
                        </button>
                        <button class="btn btn-secondary" onclick="repairPool('${poolName}')">
                            <i class="fas fa-wrench"></i> Repair Pool
                        </button>
                        <button class="btn btn-warning" onclick="exportPool('${poolName}')">
                            <i class="fas fa-download"></i> Export Pool
                        </button>
                    </div>
                </div>
                <div class="modal-footer">
                    <button onclick="closeManagePoolModal()" class="btn btn-secondary">Close</button>
                </div>
            </div>
        </div>
    `;
    
    // Add modal to DOM
    document.body.insertAdjacentHTML('beforeend', modalHtml);
    document.body.classList.add('modal-open');
    
    // Add modal functions
    window.closeManagePoolModal = () => {
        const modal = document.getElementById('managePoolModal');
        if (modal) {
            modal.remove();
            document.body.classList.remove('modal-open');
        }
        delete window.closeManagePoolModal;
        delete window.scrubPool;
        delete window.repairPool;
        delete window.exportPool;
    };
    
    window.scrubPool = async (name) => {
        PersistenceCore.showNotification(`๐Ÿงน Starting scrub for pool "${name}"`, 'info');
        // TODO: Implement pool scrub
    };
    
    window.repairPool = async (name) => {
        PersistenceCore.showNotification(`๐Ÿ”ง Starting repair for pool "${name}"`, 'info');
        // TODO: Implement pool repair
    };
    
    window.exportPool = async (name) => {
        PersistenceCore.showNotification(`๐Ÿ“ค Exporting pool "${name}"`, 'info');
        // TODO: Implement pool export
    };
}

/**
 * Create snapshot of storage pool
 * @param {string} poolName - Pool name
 * @returns {Promise<void>}
 */
async function snapshotPool(poolName) {
    console.log(`๐Ÿ“ธ Creating snapshot for pool: ${poolName}`);
    
    try {
        const snapshotName = `${poolName}-${Date.now()}`;
        await PersistenceCore.apiPost(`/storage/pools/${poolName}/snapshots`, {
            name: snapshotName,
            description: `Snapshot of ${poolName} created from UI`
        });
        
        PersistenceCore.showNotification(`Snapshot "${snapshotName}" created successfully`, 'success');
        
    } catch (error) {
        console.error('โŒ Failed to create pool snapshot:', error);
        PersistenceCore.showNotification('Failed to create pool snapshot', 'error');
    }
}

// =============================================================================
// STORAGE MONITORING
// =============================================================================

/**
 * Start storage monitoring with automatic refresh
 */
function startStorageMonitoring() {
    console.log('๐Ÿ’พ Starting storage monitoring...');
    
    // Clear existing interval
    if (storageState.refreshInterval) {
        clearInterval(storageState.refreshInterval);
    }
    
    // Set up refresh interval
    storageState.refreshInterval = setInterval(async () => {
        if (!storageState.isLoading) {
            await refreshStorage();
        }
    }, PersistenceCore.config.REFRESH_INTERVALS.STORAGE_DATA);
    
    // Initial refresh
    refreshStorage();
}

/**
 * Stop storage monitoring
 */
function stopStorageMonitoring() {
    console.log('โน๏ธ Stopping storage monitoring...');
    
    if (storageState.refreshInterval) {
        clearInterval(storageState.refreshInterval);
        storageState.refreshInterval = null;
    }
}

// =============================================================================
// INITIALIZATION
// =============================================================================

/**
 * Initialize storage module
 */
function initializeStorageModule() {
    console.log('๐Ÿ’พ Initializing storage management module...');
    
    // Start monitoring if authenticated
    if (PersistenceAuth.state.isAuthenticated) {
        startStorageMonitoring();
    }
    
    // Listen for authentication changes
    window.addEventListener('auth-state-changed', (event) => {
        if (event.detail.isAuthenticated) {
            startStorageMonitoring();
        } else {
            stopStorageMonitoring();
        }
    });
}

// Initialize on DOM ready
document.addEventListener('DOMContentLoaded', initializeStorageModule);

// =============================================================================
// EXPORT FOR MODULE SYSTEM
// =============================================================================

window.PersistenceStorage = {
    state: storageState,
    refreshStorage,
    getStorageStats,
    createPool,
    importPool,
    managePool,
    snapshotPool,
    startStorageMonitoring,
    stopStorageMonitoring,
    initializeStorageModule
};

console.log('โœ… PersistenceOS Storage Management Module loaded');
openSUSE Build Service is sponsored by