//go:build darwin
// +build darwin

package client

import (
	"fmt"
	"log"
	"net"
	"os/exec"
	"time"

	"tailscale-clone/internal/types"
	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)

// macOS-specific WireGuard interface management
func (c *Client) createInterface() error {
	// Check if interface already exists
	_, err := c.wgClient.Device(c.interfaceName)
	if err == nil {
		log.Printf("Interface %s already exists", c.interfaceName)
		return nil
	}

	// On macOS, we use utun interfaces for WireGuard
	// The interface creation is typically handled by the WireGuard tools
	log.Printf("Creating WireGuard interface %s on macOS", c.interfaceName)
	
	// Check if WireGuard tools are installed
	cmd := exec.Command("which", "wg")
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("WireGuard tools not found. Please install with: brew install wireguard-tools")
	}

	// Note: On macOS, interface creation is typically handled by the WireGuard tools
	// This is a placeholder - you'd need to integrate with the WireGuard macOS tools
	log.Printf("Interface %s creation delegated to WireGuard tools", c.interfaceName)
	
	return nil
}

func (c *Client) setupSubnetRouting() error {
	if !c.isSubnetRouter || len(c.subnets) == 0 {
		return nil
	}

	log.Printf("Setting up subnet routing on macOS for: %v", c.subnets)
	
	// Enable IP forwarding on macOS
	cmd := exec.Command("sysctl", "-w", "net.inet.ip.forwarding=1")
	if err := cmd.Run(); err != nil {
		log.Printf("Warning: Failed to enable IP forwarding: %v", err)
	}

	// Add routes for advertised subnets using macOS route command
	for _, subnet := range c.subnets {
		cmd := exec.Command("route", "-n", "add", subnet, "-interface", c.interfaceName)
		if err := cmd.Run(); err != nil {
			log.Printf("Warning: Failed to add route for %s: %v", subnet, err)
		}
	}

	log.Printf("Subnet routing setup complete for: %v", c.subnets)
	return nil
}

func (c *Client) updateSubnetRouting() error {
	// Remove old routes
	cmd := exec.Command("route", "-n", "flush")
	if err := cmd.Run(); err != nil {
		log.Printf("Warning: Failed to flush routes: %v", err)
	}

	// Add routes for each subnet router
	for _, route := range c.subnetRoutes {
		if !route.Active {
			continue
		}

		// Get WireGuard device info
		device, err := c.wgClient.Device(c.interfaceName)
		if err != nil {
			continue
		}

		for _, peer := range device.Peers {
			if peer.Endpoint == nil {
				continue
			}
			
			for _, subnet := range route.Subnets {
				// Use macOS route command
				cmd := exec.Command("route", "-n", "add", subnet, peer.Endpoint.IP.String())
				if err := cmd.Run(); err != nil {
					log.Printf("Warning: Failed to add route for %s via %s: %v", subnet, peer.Endpoint.IP, err)
				}
			}
		}
	}

	return nil
} 

// macOS-specific interface configuration
func (c *Client) configureInterfacePlatform(networkCIDR string, peers []types.Peer) error {
	// Parse private key
	privateKeyBytes, err := hexToBytes(c.privateKey)
	if err != nil {
		return fmt.Errorf("invalid private key: %v", err)
	}

	// Set private key
	key, err := wgtypes.NewKey(privateKeyBytes)
	if err != nil {
		return fmt.Errorf("failed to create key: %v", err)
	}

	// Configure device
	cfg := wgtypes.Config{
		PrivateKey: &key,
		ListenPort: nil, // Let WireGuard choose a random port
	}

	if err := c.wgClient.ConfigureDevice(c.interfaceName, cfg); err != nil {
		return fmt.Errorf("failed to configure device: %v", err)
	}

	// Add IP address using ifconfig (macOS)
	cmd := exec.Command("ifconfig", c.interfaceName, "inet", fmt.Sprintf("%s/24", c.ip))
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to add IP address: %v", err)
	}

	// Add peers
	return c.updateWireGuardPeers(peers)
} 