const AWS = require('aws-sdk');
const fs = require('fs');
const path = require('path');

const sshPath = process.env.USERPROFILE || process.env.HOME;
const vaultPath = path.join(sshPath, '.ssh');

const civo = new AWS.S3({
  endpoint: 'https://objectstore.nyc1.civo.com',
  accessKeyId: process.env.CIVO_ACCESS_KEY || '0UZ69TH03Q292DMTB82B',
  secretAccessKey: process.env.CIVO_SECRET_KEY || 'JJ5XXZYvoWdnqBCNP5oREjACyrXeH6EgSqeSybT7',
  s3ForcePathStyle: true,
  signatureVersion: 'v4'
});

const euronodes = new AWS.S3({
  endpoint: 'https://eu-west-1.euronodes.com',
  accessKeyId: process.env.EURONODES_ACCESS_KEY || 'XZNFA56V35MUY605XOUL',
  secretAccessKey: process.env.EURONODES_SECRET_KEY || 'FYATWkgSafaEMRQlFNdSQ6BoCSxG74MY9Cd7D8AF',
  s3ForcePathStyle: true,
  signatureVersion: 'v4'
});

async function listObjects(s3, bucket, prefix) {
  return new Promise((resolve, reject) => {
    s3.listObjectsV2({ Bucket: bucket, Prefix: prefix }, (err, data) => {
      if (err) reject(err);
      else resolve(data.Contents || []);
    });
  });
}

async function uploadFile(s3, bucket, key, body) {
  return new Promise((resolve, reject) => {
    s3.putObject({ Bucket: bucket, Key: key, Body: body }, (err, data) => {
      if (err) reject(err);
      else resolve(data);
    });
  });
}

async function downloadFile(s3, bucket, key) {
  return new Promise((resolve, reject) => {
    s3.getObject({ Bucket: bucket, Key: key }, (err, data) => {
      if (err) reject(err);
      else resolve(data.Body);
    });
  });
}

async function syncToCloud() {
  console.log('=== Sincronizando ~/.ssh/ para Object Storages ===\n');
  
  const files = fs.readdirSync(vaultPath).filter(f => 
    !f.startsWith('known_hosts') && 
    !f.endsWith('.pub') &&
    f !== 'authorized_keys' &&
    !fs.statSync(path.join(vaultPath, f)).isDirectory()
  );
  console.log(`Encontrados ${files.length} arquivos locais\n`);
  
  for (const file of files) {
    const filePath = path.join(vaultPath, file);
    const key = `ssh/${file}`;
    const body = fs.readFileSync(filePath);
    
    try {
      await uploadFile(civo, 'rede5', `vault/${key}`, body);
      console.log(`[CIVO] ✅ ${key}`);
    } catch (err) {
      console.log(`[CIVO] ❌ ${key}: ${err.message}`);
    }
    
    try {
      await uploadFile(euronodes, 'vault', key, body);
      console.log(`[EURONODES] ✅ ${key}`);
    } catch (err) {
      console.log(`[EURONODES] ❌ ${key}: ${err.message}`);
    }
  }
}

async function syncFromCloud() {
  console.log('=== Sincronizando Object Storages para ~/.ssh/ ===\n');
  
  const civoFiles = await listObjects(civo, 'rede5', 'vault/ssh/');
  console.log(`Civo: ${civoFiles.length} arquivos`);
  
  for (const obj of civoFiles) {
    const key = obj.Key.replace('vault/', '');
    const filePath = path.join(vaultPath, path.basename(key));
    
    try {
      const body = await downloadFile(civo, 'rede5', obj.Key);
      fs.writeFileSync(filePath, body);
      console.log(`[DOWNLOAD] ✅ ${key}`);
    } catch (err) {
      console.log(`[DOWNLOAD] ❌ ${key}: ${err.message}`);
    }
  }
}

async function syncCivoToEuronodes() {
  console.log('=== Sincronizando Civo -> Euronodes ===\n');
  
  const civoFiles = await listObjects(civo, 'rede5', 'vault/ssh/');
  console.log(`Encontrados ${civoFiles.length} arquivos no Civo\n`);
  
  for (const obj of civoFiles) {
    const key = obj.Key.replace('vault/', '');
    
    try {
      const body = await downloadFile(civo, 'rede5', obj.Key);
      await uploadFile(euronodes, 'vault', key, body);
      console.log(`[EURONODES] ✅ ${key}`);
    } catch (err) {
      console.log(`[EURONODES] ❌ ${key}: ${err.message}`);
    }
  }
}

async function listCloud() {
  console.log('=== Listando arquivos nos Object Storages ===\n');
  
  const civoFiles = await listObjects(civo, 'rede5', 'vault/ssh/');
  console.log(`Civo (rede5/vault/ssh/): ${civoFiles.length} arquivos`);
  civoFiles.forEach(f => console.log(`  ${f.Key}`));
  
  console.log('');
  
  const euronodesFiles = await listObjects(euronodes, 'vault', 'ssh/');
  console.log(`Euronodes (vault/ssh/): ${euronodesFiles.length} arquivos`);
  euronodesFiles.forEach(f => console.log(`  ${f.Key}`));
}

const action = process.argv[2] || 'list';

switch (action) {
  case 'upload':
    syncToCloud();
    break;
  case 'download':
    syncFromCloud();
    break;
  case 'sync-civo':
    syncCivoToEuronodes();
    break;
  case 'list':
  default:
    listCloud();
}
