## Nimpak Bridge Adapter
##
## This module bridges the new Resolver system with the existing Nimpak adapters
## (AUR, Pacman, Nix, etc.). It allows the Resolver to query and install packages
## from these external sources using the unified SourceAdapter interface.
##
## Philosophy:
## - Reuse existing robust adapters
## - Provide immediate access to 100,000+ packages
## - Unified interface for all package sources

import std/[options, json, strutils, sequtils, times]
import ./source_adapter
import ./variant_types
import ../../nimpak/adapters/aur
import ../../nimpak/grafting
import ../../nimpak/cas as nimpak_cas

type
  NimpakBridgeAdapter* = ref object of SourceAdapter
    aurAdapter*: AURAdapter
    # Future: Add pacmanAdapter, nixAdapter, etc.

# Constructor
proc newNimpakBridgeAdapter*(priority: int = 40): NimpakBridgeAdapter =
  ## Create a new bridge adapter
  result = NimpakBridgeAdapter(
    name: "nimpak-bridge",
    class: Flexible, # AUR is source-based, so Flexible
    priority: priority,
    aurAdapter: newAURAdapter()
  )

# Helper to convert AUR info to PackageMetadata
proc toPackageMetadata(info: JsonNode): PackageMetadata =
  var variants: seq[VariantProfile] = @[]
  
  # Create a default variant profile
  var defaultProfile = newVariantProfile()
  defaultProfile.calculateHash()
  variants.add(defaultProfile)
  
  # Convert dependencies
  var dependencies: seq[VariantDemand] = @[]
  if info.hasKey("depends"):
    for dep in info["depends"]:
      dependencies.add(VariantDemand(
        packageName: dep.getStr(),
        variantProfile: newVariantProfile(), # Default profile for deps
        optional: false
      ))
      
  if info.hasKey("makedepends"):
    for dep in info["makedepends"]:
      dependencies.add(VariantDemand(
        packageName: dep.getStr(),
        variantProfile: newVariantProfile(),
        optional: false # Build deps are required for build
      ))

  result = PackageMetadata(
    name: info["name"].getStr(),
    version: info["version"].getStr(),
    availableVariants: variants,
    dependencies: dependencies,
    sourceHash: "aur-" & info["version"].getStr(), # Simple hash for now
    buildTime: 300 # Estimate 5 mins
  )

# Check if adapter can satisfy a demand
method canSatisfy*(adapter: NimpakBridgeAdapter, demand: VariantDemand): PackageAvailability =
  ## Check if AUR has the package
  
  # For now, we only check AUR
  # In future, we'll check other adapters too
  
  let validationResult = adapter.aurAdapter.validatePackage(demand.packageName)
  if validationResult.isOk and validationResult.value:
    return Available
  else:
    return Unavailable

# Get package metadata
method getVariant*(adapter: NimpakBridgeAdapter, demand: VariantDemand): Option[PackageMetadata] =
  ## Get package info from AUR
  
  let infoResult = adapter.aurAdapter.getPackageInfo(demand.packageName)
  if infoResult.isOk:
    return some(toPackageMetadata(infoResult.value))
  else:
    return none(PackageMetadata)

# Synthesize (Build/Graft) package
method synthesize*(adapter: NimpakBridgeAdapter, demand: VariantDemand): source_adapter.Result[CasId, BuildError] =
  ## Graft package from AUR
  
  # We use a dummy cache for now as the bridge doesn't manage the cache directly
  # The AUR adapter manages its own caching
  let cache = GraftingCache() 
  
  let graftResult = adapter.aurAdapter.graftPackage(demand.packageName, cache)
  
  if graftResult.success:
    # Return the package ID as the CAS ID (since we don't have the real CAS ID from graft yet)
    # In a real implementation, graftPackage should return the CAS ID
    return source_adapter.ok[CasId, BuildError](newCasId("aur-" & demand.packageName))
  else:
    return source_adapter.err[CasId, BuildError](BuildError(
      message: "Failed to graft package from AUR",
      exitCode: 1,
      buildLog: graftResult.errors.join("\n")
    ))
