import numpy as np

class HDGLResource:
    def __init__(self, id, kind):
        self.id = id
        self.kind = kind            # "RAM", "CPU", "GPU", "SWAP", "NET"
        self.energy = 0.0           # analog energy level (0–1)
        self.traces = []            # weak decayed states
        self.tension = 0.0          # harmonic tension

    def inject(self, data: bytes = None, intensity: float = 0.1):
        if data is not None:
            # Convert to normalized analog waveform
            analog = np.frombuffer(data, dtype=np.uint8) / 255.0
            self.traces.append(analog)
            self.energy = max(self.energy, np.mean(analog))
        else:
            self.energy = min(1.0, self.energy + intensity)

    def harmonic_fusion(self):
        # Analog superposition of traces and energy
        if not self.traces:
            return
        fused = np.mean(np.stack(self.traces), axis=0)
        self.traces = [fused * 0.9]  # decay traces
        self.energy = np.mean(fused)
        # High-tension channels naturally attract traces
        if self.tension > 0.5:
            self.energy = min(1.0, self.energy + 0.05)

    def update_tension(self):
        # Tension emerges naturally from analog energy
        self.tension = self.energy


class HDGLLattice:
    def __init__(self):
        # Create analog channels for all device/resource types
        self.channels = [
            HDGLResource(i, kind)
            for i, kind in enumerate(["RAM", "CPU", "GPU", "SWAP", "NET"]*4)
        ]

    def map_resource(self, data: bytes = None, kind: str = "RAM"):
        # Assign data to lowest-tension channel of requested kind
        candidates = [c for c in self.channels if c.kind == kind]
        ch = min(candidates, key=lambda c: c.tension)
        ch.inject(data)

    def evolve(self):
        # All channels continuously harmonize
        for ch in self.channels:
            ch.harmonic_fusion()
            ch.update_tension()

    def status(self):
        return {f"{ch.kind}-{ch.id}": ch.energy for ch in self.channels}
