import numpy as np
import matplotlib.pyplot as plt

# -------------------------
# HDGL Superposition VM
# -------------------------
class HDGL_VM_32:
    def __init__(self, blend_factor=0.05):
        self.phi = 1.6180339887
        self.strands = ['A','B','C','D','E','F','G','H']
        self.D = np.zeros(32)
        self.omega = 0.0
        self.blend_factor = blend_factor
        self.ip = 0

        # Shared resonance mapping
        self.resonance_map = [2,6,10,14,18,22,26,30]

        # History for plotting
        self.history_D = []
        self.history_omega = []

        # Filesystem
        self.fs = {}
        self.init_filesystem()

        # Plotting
        self.fig, self.ax = plt.subplots(2,1, figsize=(12,6))
        self.lines_D = [self.ax[0].plot([],[],label=f"D{i+1}")[0] for i in range(32)]
        self.line_omega, = self.ax[1].plot([],[],label="Omega")
        self.ax[0].set_title("D1-D32 Registers"); self.ax[1].set_title("Omega")
        self.ax[0].set_xlabel("Step"); self.ax[1].set_xlabel("Step")
        self.ax[0].set_ylabel("Value"); self.ax[1].set_ylabel("Value")
        self.ax[0].legend(ncol=4, fontsize=8); self.ax[1].legend()
        plt.ion(); plt.show()

    # Step analog superposition
    def step(self):
        D_prev = self.D.copy()
        for i in range(32):
            res_val = np.sum([D_prev[r] for r in self.resonance_map if r != i])
            self.D[i] = np.tanh(D_prev[i] + self.blend_factor*(D_prev[i]*self.phi + res_val + self.omega))
        self.omega += 0.01 * self.blend_factor
        self.ip += 1
        self.history_D.append(self.D.copy())
        self.history_omega.append(self.omega)
        self.update_plot()

    def run(self, steps=None):
        count = 0
        while steps is None or count < steps:
            self.step()
            count += 1

    # Numeric REPL
    def numeric_repl(self):
        self.print("HDGL VM 32-Slot Numeric REPL. Type 'help'.")
        while True:
            cmd = self.input("HDGL32-NUM> ").strip().split()
            if not cmd: continue
            instr = cmd[0].lower()
            if instr in ['quit','exit']: break
            elif instr=='help':
                self.print("step [n], run [n], add Dn Dm, mul Dn val, set Dn val, state, reset, fs <cmd>, help, exit")
            elif instr=='step': n=int(cmd[1]) if len(cmd)>1 else 1; [self.step() for _ in range(n)]; self.show_state()
            elif instr=='run': n=int(cmd[1]) if len(cmd)>1 else None; self.run(steps=n); self.show_state()
            elif instr=='add' and len(cmd)==3: i,j=self.parse_reg(cmd[1]),self.parse_reg(cmd[2]); self.D[i]=np.tanh(self.D[i]+self.D[j]); self.show_state()
            elif instr=='mul' and len(cmd)==3: i=self.parse_reg(cmd[1]); val=float(cmd[2]); self.D[i]=np.tanh(self.D[i]*val); self.show_state()
            elif instr=='set' and len(cmd)==3: i=self.parse_reg(cmd[1]); val=float(cmd[2]); self.D[i]=np.tanh(val); self.show_state()
            elif instr=='state': self.show_state()
            elif instr=='reset': self.__init__(blend_factor=self.blend_factor); self.print("VM reset.")
            elif instr=='fs': self.fs_command(" ".join(cmd))
            else: self.print("Unknown instruction. Type 'help'.")

    # Register parser
    def parse_reg(self, reg_name):
        if reg_name.upper().startswith("D"):
            idx=int(reg_name[1:])-1
            if 0<=idx<32: return idx
        raise ValueError(f"Invalid register: {reg_name}")

    # Filesystem helpers
    def fs_command(self, cmd):
        parts=cmd.split()
        if len(parts)<2: return self.print("FS commands: ls, cat <file>, echo <file> 'text', rm <file>")
        fs_cmd=parts[1].lower()
        if fs_cmd=='ls': self.print(list(self.fs.keys()))
        elif fs_cmd=='cat' and len(parts)>=3: self.print(self.fs.get(parts[2],f"File '{parts[2]}' not found."))
        elif fs_cmd=='rm' and len(parts)>=3: self.print("Deleted "+parts[2] if self.fs.pop(parts[2],None) else f"File '{parts[2]}' not found.")
        elif fs_cmd=='echo' and len(parts)>=4: self.fs[parts[2]]=" ".join(parts[3:]); self.print(f"Written to {parts[2]}")
        else: self.print("Unknown FS command.")

    # Utility I/O & Plot
    def input(self, prompt=""): return input(prompt)
    def print(self, *args): print(*args)
    def show_state(self): self.print(f"D1-D32:{np.round(self.D,5)} Omega:{self.omega:.5f}")
    def update_plot(self):
        for i,line in enumerate(self.lines_D): line.set_data(range(len(self.history_D)), [h[i] for h in self.history_D])
        self.line_omega.set_data(range(len(self.history_omega)), self.history_omega)
        for ax in self.ax: ax.relim(); ax.autoscale_view()
        self.fig.canvas.draw(); self.fig.canvas.flush_events()

    # Filesystem init
    def init_filesystem(self):
        self.fs['/boot']={
            'grub.cfg':{
                'menu':[
                    ("Standard Kernel", 0.1),
                    ("Fractal Kernel", 0.2)
                ]
            },
            'readme.txt':"Welcome to HDGL 32-Slot VM - Analog φ Lattice"
        }

# -------------------------
# Kernel / Linux Init
# -------------------------
def hdgl_kernel_boot(vm: HDGL_VM_32):
    vm.print("Booting HDGL Kernel...")
    for _ in range(20):
        vm.step()
    vm.print("Kernel boot complete.")

def hdgl_linux_init(vm: HDGL_VM_32):
    vm.print("Initializing HDGL Linux environment...")
    # create /bin and basic files
    vm.fs['/bin'] = {}
    vm.fs['/boot/kernel.bin'] = "HDGL_KERNEL_INIT_SEQUENCE_1234567890"
    vm.print("Linux init complete.")

# -------------------------
# Full /bin Suite Generator
# -------------------------
def hdgl_generate_binaries(vm: HDGL_VM_32):
    # basic binaries
    vm.fs["/bin/ls"] = [("ls", None)]
    vm.fs["/bin/cat"] = [("cat", None)]
    vm.fs["/bin/echo"] = [("echo", None)]
    vm.fs["/bin/sh"] = [("repl", None)]

def hdgl_generate_full_bin_suite(vm: HDGL_VM_32):
    vm.print("Generating full HDGL /bin suite...")
    hdgl_generate_binaries(vm)
    additional_bins = ["mkdir","rm","touch","mv","cp","pwd","whoami","date","clear"]
    for b in additional_bins:
        vm.fs[f"/bin/{b}"] = [(b,None)]
    vm.print("Full binary suite created: " + ", ".join(list(vm.fs["/bin"].keys())))

# -------------------------
# HDGL Binary Executor
# -------------------------
def hdgl_exec(vm: HDGL_VM_32, binary_name: str, operand=None):
    binary = vm.fs.get(f"/bin/{binary_name}", None)
    if binary is None:
        print(f"Binary '{binary_name}' not found.")
        return
    for instr,_ in binary:
        if instr=="ls": print(list(vm.fs.keys()))
        elif instr=="cat" and operand: print(vm.fs.get(operand,f"File '{operand}' not found."))
        elif instr=="echo" and operand: fname,text=operand; vm.fs[fname]=text; print(f"Written to {fname}")
        elif instr=="repl": vm.numeric_repl()
        elif instr=="mkdir" and operand: vm.fs[operand]={}; print(f"Directory '{operand}' created.")
        elif instr=="rm" and operand: print(f"Removed '{operand}'" if vm.fs.pop(operand,None) else f"File '{operand}' not found.")
        elif instr=="touch" and operand: vm.fs[operand]=""; print(f"Empty file '{operand}' created.")
        elif instr=="mv" and operand: src,dst=operand; vm.fs[dst]=vm.fs.pop(src); print(f"Renamed '{src}' -> '{dst}'")
        elif instr=="cp" and operand: src,dst=operand; vm.fs[dst]=vm.fs[src]; print(f"Copied '{src}' -> '{dst}'")
        elif instr=="pwd": print("/")
        elif instr=="whoami": print("HDGL_USER")
        elif instr=="date": print("HDGL_Lattice_Time:", len(vm.history_D))
        elif instr=="clear": 
            for i in range(16,24): vm.D[i]=0
            print("Console cleared.")
        else: print(f"Unknown instruction: {instr}")

# -------------------------
# Launch full HDGL Linux
# -------------------------
if __name__=="__main__":
    vm = HDGL_VM_32()
    hdgl_kernel_boot(vm)
    hdgl_linux_init(vm)
    hdgl_generate_full_bin_suite(vm)

    # Example usage
    hdgl_exec(vm, "ls")
    hdgl_exec(vm, "touch", "file1.txt")
    hdgl_exec(vm, "mkdir", "mydir")
    hdgl_exec(vm, "echo", ("file1.txt","Hello HDGL Linux!"))
    hdgl_exec(vm, "cat", "file1.txt")
    hdgl_exec(vm, "pwd")
    hdgl_exec(vm, "whoami")
    hdgl_exec(vm, "date")
    hdgl_exec(vm, "clear")

    # Launch interactive shell
    hdgl_exec(vm, "sh")
