{
  "openapi": "3.0.3",
  "info": {
    "title": "VVMM API",
    "description": "VVMM (Virtual Machine & Process Monitoring) REST API for system monitoring, agent management, and remote operations.",
    "version": "1.2.6",
    "contact": {
      "name": "VVMM"
    },
    "license": {
      "name": "MIT"
    }
  },
  "servers": [
    {
      "url": "http://localhost:9200",
      "description": "Local development server"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Password passed as Bearer token"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "Agent": {
        "type": "object",
        "properties": {
          "agent_id": { "type": "string" },
          "display_name": { "type": "string" },
          "notes": { "type": "string" },
          "status": { "type": "string", "enum": ["pending", "active", "disabled"] },
          "network_mode": { "type": "string" },
          "group": { "type": "string" },
          "created_at": { "type": "string", "format": "date-time" },
          "expire_at": { "type": "string", "format": "date-time", "nullable": true },
          "last_connected": { "type": "string", "format": "date-time", "nullable": true },
          "connected_at": { "type": "integer", "nullable": true },
          "last_seen": { "type": "integer", "nullable": true },
          "channel": { "type": "string", "nullable": true },
          "remote_addr": { "type": "string", "nullable": true },
          "public_ip": { "type": "string", "nullable": true },
          "hostname": { "type": "string", "nullable": true },
          "os": { "type": "string", "nullable": true },
          "cpu_usage": { "type": "number", "format": "float", "nullable": true },
          "memory_used": { "type": "integer", "nullable": true },
          "memory_total": { "type": "integer", "nullable": true },
          "net_rx_sec": { "type": "integer", "nullable": true },
          "net_tx_sec": { "type": "integer", "nullable": true },
          "metadata": { "$ref": "#/components/schemas/AgentMetadata" },
          "monitored_processes": { "type": "object", "nullable": true }
        }
      },
      "AgentMetadata": {
        "type": "object",
        "properties": {
          "display_name": { "type": "string" },
          "ip": { "type": "string" },
          "location": { "type": "string" },
          "group": { "type": "string" },
          "expiry_date": { "type": "string" },
          "payment_due": { "type": "string" },
          "payment_cycle": { "type": "string" },
          "payment_amount": { "type": "string" }
        }
      },
      "SystemInfo": {
        "type": "object",
        "properties": {
          "hostname": { "type": "string" },
          "os_name": { "type": "string" },
          "os_version": { "type": "string" },
          "kernel_version": { "type": "string" },
          "uptime_secs": { "type": "integer" },
          "cpu": { "$ref": "#/components/schemas/CpuInfo" },
          "memory": { "$ref": "#/components/schemas/MemoryInfo" },
          "disks": { "type": "array", "items": { "$ref": "#/components/schemas/DiskInfo" } },
          "network": { "type": "array", "items": { "$ref": "#/components/schemas/NetworkInfo" } },
          "processes": { "type": "array", "items": { "$ref": "#/components/schemas/ProcessInfo" } },
          "timestamp": { "type": "integer" },
          "public_ip": { "type": "string", "nullable": true }
        }
      },
      "CpuInfo": {
        "type": "object",
        "properties": {
          "usage_percent": { "type": "number", "format": "float" },
          "core_count": { "type": "integer" },
          "brand": { "type": "string" },
          "frequency_mhz": { "type": "integer" }
        }
      },
      "MemoryInfo": {
        "type": "object",
        "properties": {
          "total_bytes": { "type": "integer" },
          "used_bytes": { "type": "integer" },
          "available_bytes": { "type": "integer" },
          "swap_total_bytes": { "type": "integer" },
          "swap_used_bytes": { "type": "integer" }
        }
      },
      "DiskInfo": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "mount_point": { "type": "string" },
          "total_bytes": { "type": "integer" },
          "used_bytes": { "type": "integer" },
          "file_system": { "type": "string" }
        }
      },
      "NetworkInfo": {
        "type": "object",
        "properties": {
          "interface": { "type": "string" },
          "rx_bytes": { "type": "integer" },
          "tx_bytes": { "type": "integer" }
        }
      },
      "ProcessInfo": {
        "type": "object",
        "properties": {
          "pid": { "type": "integer" },
          "name": { "type": "string" },
          "cpu_usage": { "type": "number", "format": "float" },
          "memory_bytes": { "type": "integer" },
          "virtual_memory_bytes": { "type": "integer" },
          "status": { "type": "string" },
          "user": { "type": "string", "nullable": true }
        }
      },
      "MonitoredProcess": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "process_type": { "type": "string", "enum": ["docker", "binary"] },
          "status": { "type": "string" },
          "pid": { "type": "integer", "nullable": true },
          "uptime_secs": { "type": "integer", "nullable": true },
          "cpu_usage": { "type": "number", "format": "float", "nullable": true },
          "memory_bytes": { "type": "integer", "nullable": true },
          "restart_count": { "type": "integer" },
          "last_exit_code": { "type": "integer", "nullable": true },
          "error_message": { "type": "string", "nullable": true }
        }
      },
      "DataPoint": {
        "type": "object",
        "properties": {
          "ts": { "type": "integer" },
          "cpu": { "type": "number", "format": "float" },
          "mem_pct": { "type": "number", "format": "float" },
          "mem_used": { "type": "integer" },
          "mem_total": { "type": "integer" },
          "net_rx": { "type": "integer" },
          "net_tx": { "type": "integer" },
          "disk_used": { "type": "integer" },
          "disk_total": { "type": "integer" }
        }
      },
      "ExecRequest": {
        "type": "object",
        "required": ["command"],
        "properties": {
          "command": { "type": "string" },
          "args": { "type": "array", "items": { "type": "string" } }
        }
      },
      "BatchExecRequest": {
        "type": "object",
        "required": ["command"],
        "properties": {
          "command": { "type": "string" },
          "args": { "type": "array", "items": { "type": "string" } },
          "target": { "type": "string", "description": "all, group:<name>, or agent:<id>" }
        }
      },
      "FileUploadRequest": {
        "type": "object",
        "required": ["filename", "path", "content"],
        "properties": {
          "filename": { "type": "string" },
          "path": { "type": "string" },
          "content": { "type": "string", "description": "Base64 encoded file content" },
          "permissions": { "type": "string", "default": "0644" },
          "target": { "type": "string", "description": "all, group:<name>, or agent:<id>" }
        }
      },
      "UpdateBinaryRequest": {
        "type": "object",
        "properties": {
          "url": { "type": "string", "description": "URL to download binary from" },
          "content": { "type": "string", "description": "Base64 encoded binary content" },
          "target": { "type": "string", "description": "all, group:<name>, or agent:<id>" }
        }
      },
      "ProcessControlRequest": {
        "type": "object",
        "required": ["name", "action"],
        "properties": {
          "name": { "type": "string" },
          "action": { "type": "string", "enum": ["start", "stop", "restart"] }
        }
      },
      "CreateAgentRequest": {
        "type": "object",
        "required": ["display_name"],
        "properties": {
          "display_name": { "type": "string" },
          "notes": { "type": "string" },
          "group": { "type": "string" },
          "network_mode": { "type": "string", "enum": ["public", "wireguard"] },
          "server_host": { "type": "string" },
          "server_port": { "type": "integer" },
          "use_tls": { "type": "boolean" }
        }
      },
      "UpdateMetadataRequest": {
        "type": "object",
        "properties": {
          "display_name": { "type": "string" },
          "group": { "type": "string" },
          "ip": { "type": "string" },
          "location": { "type": "string" },
          "expiry_date": { "type": "string" },
          "payment_due": { "type": "string" },
          "payment_cycle": { "type": "string" },
          "payment_amount": { "type": "string" }
        }
      },
      "ContainerLogsRequest": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string" },
          "tail": { "type": "integer", "default": 100 }
        }
      }
    }
  },
  "security": [{"BearerAuth": []}],
  "paths": {
    "/api/health": {
      "get": {
        "tags": ["System"],
        "summary": "Health check",
        "security": [],
        "responses": {
          "200": {
            "description": "Server is healthy",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "example": "ok" } } } } }
          }
        }
      }
    },
    "/api/auth/verify": {
      "get": {
        "tags": ["Auth"],
        "summary": "Verify password",
        "parameters": [
          { "name": "Authorization", "in": "header", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Valid password" },
          "401": { "description": "Invalid password" }
        }
      }
    },
    "/api/agents": {
      "get": {
        "tags": ["Agents"],
        "summary": "List all agents",
        "description": "Returns all registered agents with live data if connected",
        "responses": {
          "200": {
            "description": "List of agents",
            "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Agent" } } } }
          }
        }
      }
    },
    "/api/agents/{agent_id}": {
      "get": {
        "tags": ["Agents"],
        "summary": "Get agent details",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Agent details" },
          "404": { "description": "Agent not found" }
        }
      }
    },
    "/api/agents/{agent_id}/report": {
      "get": {
        "tags": ["Agents"],
        "summary": "Get agent system report",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "System report",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SystemInfo" } } }
          },
          "404": { "description": "No report available" }
        }
      }
    },
    "/api/agents/{agent_id}/exec": {
      "post": {
        "tags": ["Execution"],
        "summary": "Execute command on single agent",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExecRequest" } } }
        },
        "responses": {
          "202": { "description": "Command sent" },
          "404": { "description": "Agent not connected" }
        }
      }
    },
    "/api/exec": {
      "post": {
        "tags": ["Execution"],
        "summary": "Batch execute command",
        "description": "Execute command on all agents, a group, or a specific agent",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BatchExecRequest" } } }
        },
        "responses": {
          "202": {
            "description": "Command sent",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "command_id": { "type": "string" },
              "target": { "type": "string" },
              "agents_total": { "type": "integer" },
              "agents_sent": { "type": "integer" },
              "status": { "type": "string" }
            } } } }
          }
        }
      }
    },
    "/api/agents/{agent_id}/metadata": {
      "put": {
        "tags": ["Agents"],
        "summary": "Update agent metadata",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMetadataRequest" } } }
        },
        "responses": {
          "200": { "description": "Updated" },
          "404": { "description": "Agent not found" }
        }
      }
    },
    "/api/groups": {
      "get": {
        "tags": ["Agents"],
        "summary": "List all groups",
        "responses": {
          "200": {
            "description": "List of groups",
            "content": { "application/json": { "schema": { "type": "object", "properties": { "groups": { "type": "array", "items": { "type": "string" } } } } } }
          }
        }
      }
    },
    "/api/agents/{agent_id}/history": {
      "get": {
        "tags": ["History"],
        "summary": "Get agent historical data",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "since", "in": "query", "schema": { "type": "integer" }, "description": "Unix timestamp" },
          { "name": "max_points", "in": "query", "schema": { "type": "integer", "default": 1000 } }
        ],
        "responses": {
          "200": {
            "description": "Historical data points",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "agent_id": { "type": "string" },
              "since": { "type": "integer" },
              "points": { "type": "array", "items": { "$ref": "#/components/schemas/DataPoint" } }
            } } } }
          }
        }
      }
    },
    "/api/upload": {
      "post": {
        "tags": ["File Transfer"],
        "summary": "Upload file to agent(s)",
        "description": "Transfer a file to one or more agents. Content must be base64 encoded.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FileUploadRequest" } } }
        },
        "responses": {
          "202": {
            "description": "File transfer initiated",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "transfer_id": { "type": "string" },
              "target": { "type": "string" },
              "agents_total": { "type": "integer" },
              "agents_sent": { "type": "integer" },
              "status": { "type": "string" }
            } } } }
          }
        }
      }
    },
    "/api/update-binary": {
      "post": {
        "tags": ["File Transfer"],
        "summary": "Update agent binary",
        "description": "Update the vvmm-agent binary on target machines. Supports file upload or URL download.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateBinaryRequest" } } }
        },
        "responses": {
          "202": {
            "description": "Update initiated",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "update_id": { "type": "string" },
              "target": { "type": "string" },
              "agents_total": { "type": "integer" },
              "agents_sent": { "type": "integer" },
              "status": { "type": "string" }
            } } } }
          }
        }
      }
    },
    "/api/agents/{agent_id}/processes": {
      "get": {
        "tags": ["Process Management"],
        "summary": "List monitored processes for agent",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "List of processes",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "agent_id": { "type": "string" },
              "processes": { "type": "array", "items": { "$ref": "#/components/schemas/MonitoredProcess" } }
            } } } }
          }
        }
      }
    },
    "/api/agents/{agent_id}/processes/control": {
      "post": {
        "tags": ["Process Management"],
        "summary": "Control a process",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProcessControlRequest" } } }
        },
        "responses": {
          "202": { "description": "Action sent" },
          "400": { "description": "Invalid action" },
          "404": { "description": "Agent not connected" }
        }
      }
    },
    "/api/processes": {
      "get": {
        "tags": ["Process Management"],
        "summary": "List all monitored processes",
        "description": "Returns monitored processes across all connected agents",
        "responses": {
          "200": {
            "description": "All processes",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "total": { "type": "integer" },
              "processes": { "type": "array", "items": { "$ref": "#/components/schemas/MonitoredProcess" } }
            } } } }
          }
        }
      }
    },
    "/api/agents/{agent_id}/container-logs": {
      "post": {
        "tags": ["Docker"],
        "summary": "Get container logs",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContainerLogsRequest" } } }
        },
        "responses": {
          "202": { "description": "Request sent" }
        }
      }
    },
    "/api/agents/create": {
      "post": {
        "tags": ["Deployment"],
        "summary": "Create new agent",
        "description": "Register a new agent and get install token",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateAgentRequest" } } }
        },
        "responses": {
          "201": {
            "description": "Agent created",
            "content": { "application/json": { "schema": { "type": "object", "properties": {
              "agent_id": { "type": "string" },
              "install_token": { "type": "string" },
              "agent_token": { "type": "string" },
              "display_name": { "type": "string" },
              "group": { "type": "string" },
              "status": { "type": "string" },
              "network_mode": { "type": "string" },
              "install_command": { "type": "string" },
              "created_at": { "type": "string" }
            } } } }
          }
        }
      }
    },
    "/api/agents/{agent_id}/config": {
      "get": {
        "tags": ["Deployment"],
        "summary": "Get agent config",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Agent config" },
          "404": { "description": "Agent not found" }
        }
      }
    },
    "/api/agents/{agent_id}/regenerate-token": {
      "post": {
        "tags": ["Deployment"],
        "summary": "Regenerate agent token",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "New token generated" },
          "404": { "description": "Agent not found" }
        }
      }
    },
    "/api/agents/{agent_id}/delete": {
      "post": {
        "tags": ["Deployment"],
        "summary": "Delete agent",
        "parameters": [
          { "name": "agent_id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Agent deleted" },
          "404": { "description": "Agent not found" }
        }
      }
    },
    "/install.sh": {
      "get": {
        "tags": ["Installation"],
        "summary": "Get install script",
        "security": [],
        "parameters": [
          { "name": "token", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Install script" },
          "401": { "description": "Invalid token" }
        }
      }
    },
    "/download/package/{token}": {
      "get": {
        "tags": ["Installation"],
        "summary": "Download agent package",
        "security": [],
        "parameters": [
          { "name": "token", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Agent package (tar.gz)" },
          "401": { "description": "Invalid token" }
        }
      }
    },
    "/download/config/{token}": {
      "get": {
        "tags": ["Installation"],
        "summary": "Download agent config",
        "security": [],
        "parameters": [
          { "name": "token", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Agent config file" },
          "401": { "description": "Invalid token" }
        }
      }
    },
    "/download/agent": {
      "get": {
        "tags": ["Installation"],
        "summary": "Download agent binary",
        "security": [],
        "responses": {
          "200": { "description": "Agent binary" },
          "404": { "description": "Binary not found" }
        }
      }
    }
  }
}
