import { exec } from 'child_process';
import { promisify } from 'util';
import { requireApiAuth, type User } from '../../utils/apiAuth.ts';
import type { APIContext } from 'astro';

const execAsync = promisify(exec);

interface DiskSpaceResponse {
  total: number;
  used: number;
  available: number;
  usedPercent: number;
  totalFormatted: string;
  usedFormatted: string;
  availableFormatted: string;
}

export async function GET({ request }: APIContext): Promise<Response> {
  // Check authentication
  const { user, error: authError, setCookieHeader } = await requireApiAuth(request);
  if (authError) return authError;

  // Check authorization - must have 'admin' or 'trip' role
  const userRoles = user?.roles || [];
  const hasAccess = userRoles.includes('admin') || userRoles.includes('trip');
  
  if (!hasAccess) {
    return new Response(JSON.stringify({ 
      error: 'Forbidden', 
      message: 'Insufficient permissions. Requires admin or trip role.' 
    }), {
      status: 403,
      headers: { 'Content-Type': 'application/json' },
    });
  }

  try {
    // Get disk space for root filesystem
    const { stdout } = await execAsync("df -B1 / | tail -1 | awk '{print $2,$3,$4}'");
    const [total, used, available] = stdout.trim().split(/\s+/).map(Number);

    if (!total || !available) {
      throw new Error('Failed to parse disk space');
    }

    const usedPercent = Math.round((used / total) * 100);

    const responseHeaders = { 'Content-Type': 'application/json' };
    if (setCookieHeader) {
      responseHeaders['Set-Cookie'] = setCookieHeader;
    }

    return new Response(JSON.stringify({
      total,
      used,
      available,
      usedPercent,
      // Human-readable versions
      totalFormatted: formatBytes(total),
      usedFormatted: formatBytes(used),
      availableFormatted: formatBytes(available),
    }), {
      status: 200,
      headers: responseHeaders,
    });
  } catch (err) {
    console.error('Error getting disk space:', err);
    return new Response(JSON.stringify({ error: 'Failed to get disk space' }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
}

function formatBytes(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
