#!/usr/bin/env node

/**
 * TimeSafari Build Script
 * 
 * Integrates the Daily Notification Plugin with TimeSafari PWA's build system.
 * Handles platform-specific builds, tree-shaking, and SSR safety validation.
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

// Configuration
const CONFIG = {
  platforms: ['android', 'ios', 'electron'],
  bundleSizeBudget: 35, // KB
  ssrSafe: true,
  treeShaking: true
};

/**
 * Log with timestamp
 */
function log(message, level = 'INFO') {
  const timestamp = new Date().toISOString();
  console.log(`[${timestamp}] [${level}] ${message}`);
}

/**
 * Check if file exists
 */
function fileExists(filePath) {
  return fs.existsSync(filePath);
}

/**
 * Get file size in KB (gzipped)
 */
function getFileSizeKB(filePath) {
  if (!fileExists(filePath)) return 0;
  
  try {
    // Use gzip to get compressed size
    const content = fs.readFileSync(filePath);
    const zlib = require('zlib');
    const gzipped = zlib.gzipSync(content);
    return Math.round(gzipped.length / 1024 * 100) / 100;
  } catch (error) {
    // Fallback to uncompressed size
    const stats = fs.statSync(filePath);
    return Math.round(stats.size / 1024 * 100) / 100;
  }
}

/**
 * Validate SSR safety
 */
function validateSSRSafety() {
  log('Validating SSR safety...');
  
  // Only validate core files, not platform-specific implementations
  const coreFiles = [
    'src/index.ts',
    'src/timesafari-integration.ts',
    'src/timesafari-community-integration.ts'
  ];
  
  const ssrUnsafePatterns = [
    /window\./g,
    /document\./g,
    /navigator\./g
  ];
  
  let hasUnsafeCode = false;
  
  coreFiles.forEach(filePath => {
    if (!fileExists(filePath)) return;
    
    const content = fs.readFileSync(filePath, 'utf8');
    
    ssrUnsafePatterns.forEach(pattern => {
      if (pattern.test(content)) {
        log(`SSR-unsafe code found in ${filePath}`, 'WARN');
        hasUnsafeCode = true;
      }
    });
  });
  
  if (hasUnsafeCode) {
    log('SSR safety validation failed for core files', 'ERROR');
    return false;
  }
  
  // Check platform-specific files for proper guards
  const platformFiles = [
    'src/web/index.ts',
    'src/timesafari-storage-adapter.ts'
  ];
  
  platformFiles.forEach(filePath => {
    if (!fileExists(filePath)) return;
    
    const content = fs.readFileSync(filePath, 'utf8');
    
    // Check if file has proper platform guards
    const hasPlatformGuards = content.includes('typeof window') || 
                             content.includes('typeof document') ||
                             content.includes('platform check');
    
    if (!hasPlatformGuards && (content.includes('window.') || content.includes('document.'))) {
      log(`Platform-specific file ${filePath} should have platform guards`, 'WARN');
    }
  });
  
  log('SSR safety validation passed');
  return true;
}

/**
 * Validate tree-shaking
 */
function validateTreeShaking() {
  log('Validating tree-shaking...');
  
  // Check if sideEffects is set to false in package.json
  const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
  
  if (packageJson.sideEffects !== false) {
    log('sideEffects not set to false in package.json', 'WARN');
    return false;
  }
  
  // Check exports map
  if (!packageJson.exports) {
    log('exports map not defined in package.json', 'WARN');
    return false;
  }
  
  log('Tree-shaking validation passed');
  return true;
}

/**
 * Build for specific platform
 */
function buildForPlatform(platform) {
  log(`Building for platform: ${platform}`);
  
  try {
    // Set platform-specific environment variables
    process.env.TIMESAFARI_PLATFORM = platform;
    
    // Run build command
    execSync('npm run build', { stdio: 'inherit' });
    
    // Validate build output
    const expectedFiles = [
      'dist/plugin.js',
      'dist/esm/index.js',
      'dist/esm/index.d.ts'
    ];
    
    expectedFiles.forEach(file => {
      if (!fileExists(file)) {
        throw new Error(`Expected file not found: ${file}`);
      }
    });
    
    log(`Build completed for platform: ${platform}`);
    return true;
    
  } catch (error) {
    log(`Build failed for platform: ${platform} - ${error.message}`, 'ERROR');
    return false;
  }
}

/**
 * Validate bundle size
 */
function validateBundleSize() {
  log('Validating bundle size...');
  
  const bundleFiles = [
    'dist/plugin.js',
    'dist/esm/index.js'
  ];
  
  let totalSize = 0;
  
  bundleFiles.forEach(file => {
    const size = getFileSizeKB(file);
    totalSize += size;
    log(`  ${file}: ${size}KB`);
  });
  
  log(`Total bundle size: ${totalSize}KB`);
  
  if (totalSize > CONFIG.bundleSizeBudget) {
    log(`Bundle size (${totalSize}KB) exceeds budget (${CONFIG.bundleSizeBudget}KB)`, 'ERROR');
    return false;
  }
  
  log('Bundle size validation passed');
  return true;
}

/**
 * Generate build report
 */
function generateBuildReport() {
  log('Generating build report...');
  
  const report = {
    timestamp: new Date().toISOString(),
    platform: process.env.TIMESAFARI_PLATFORM || 'all',
    bundleSize: {
      plugin: getFileSizeKB('dist/plugin.js'),
      esm: getFileSizeKB('dist/esm/index.js'),
      total: getFileSizeKB('dist/plugin.js') + getFileSizeKB('dist/esm/index.js')
    },
    validation: {
      ssrSafe: CONFIG.ssrSafe,
      treeShaking: CONFIG.treeShaking,
      bundleSizeBudget: CONFIG.bundleSizeBudget
    },
    files: {
      plugin: fileExists('dist/plugin.js'),
      esm: fileExists('dist/esm/index.js'),
      types: fileExists('dist/esm/index.d.ts')
    }
  };
  
  // Write report to file
  fs.writeFileSync('dist/build-report.json', JSON.stringify(report, null, 2));
  
  log('Build report generated: dist/build-report.json');
  return report;
}

/**
 * Main build function
 */
function main() {
  log('Starting TimeSafari build process...');
  
  // Validate configuration
  if (!validateSSRSafety()) {
    process.exit(1);
  }
  
  if (!validateTreeShaking()) {
    process.exit(1);
  }
  
  // Build for all platforms
  const platform = process.env.TIMESAFARI_PLATFORM || 'all';
  
  if (platform === 'all') {
    CONFIG.platforms.forEach(p => {
      if (!buildForPlatform(p)) {
        process.exit(1);
      }
    });
  } else {
    if (!buildForPlatform(platform)) {
      process.exit(1);
    }
  }
  
  // Validate bundle size
  if (!validateBundleSize()) {
    process.exit(1);
  }
  
  // Generate build report
  const report = generateBuildReport();
  
  log('TimeSafari build process completed successfully');
  log(`Bundle size: ${report.bundleSize.total}KB`);
  log(`Platform: ${report.platform}`);
}

// Run if called directly
if (require.main === module) {
  main();
}

module.exports = {
  buildForPlatform,
  validateSSRSafety,
  validateTreeShaking,
  validateBundleSize,
  generateBuildReport
};
