# DroidScope — Development Guide

## Prerequisites

| Tool | Version | Install |
|---|---|---|
| Go | 1.23+ | https://go.dev/dl |
| Node.js | 20+ | https://nodejs.org |
| Wails CLI | v2 | `go install github.com/wailsapp/wails/v2/cmd/wails@latest` |
| Git | any | — |

> **macOS only:** Wails requires Xcode Command Line Tools — `xcode-select --install`
>
> **Linux only:** Wails requires `libgtk-3-dev libwebkit2gtk-4.0-dev` (Debian/Ubuntu) or equivalent.
>
> **Windows only:** Wails requires WebView2 (ships with Windows 11, otherwise install from Microsoft).

---

## First-time Setup

```bash
# 1. Install frontend dependencies
cd frontend-react
npm install

# 2. (Optional) Download bundled ADB binaries for distribution builds
# Skip this for local dev — the app falls back to your system ADB
bash scripts/download-adb.sh

# 3. Make sure your system ADB is accessible for local dev
# Either via ANDROID_HOME or PATH:
export ANDROID_HOME=~/Library/Android/sdk   # macOS example
# or: ensure `adb` is on your PATH
```

---

## Running in Development

```bash
bash scripts/dev.sh
```

**What `dev.sh` does, in order:**

| Step | Command | What it checks |
|---|---|---|
| 1 | `go build ./...` in `backend-go/` | Backend packages compile without errors |
| 2 | `go build ./...` in `desktop/` | Desktop Go code (app.go, main.go, embeds) compiles |
| 3 | `wails generate module` in `desktop/` | Regenerates `frontend-react/src/wailsjs/` from current `app.go` bindings |
| 4 | `npm install` + `tsc -b --noEmit` in `frontend-react/` | Installs any new deps, type-checks TypeScript |
| — | `wails dev` in `desktop/` | Starts the desktop app with hot reload |

If any step fails the script exits immediately (due to `set -e`) — fix the error and re-run.

**What happens once running:**
- Wails compiles the Go backend and opens a native desktop window
- Wails starts the Vite dev server (`npm run dev` in `frontend-react/`)
- React/TS changes hot-reload instantly without restarting
- Go changes (in `app.go`, `backend-go/`) require re-running `dev.sh`

> **When to re-run `dev.sh` vs just saving a file:**
> - Edited only `.tsx` / `.ts` / `.css` → Vite hot-reloads automatically, no restart needed
> - Edited `app.go` (added/changed a bound method) → re-run `dev.sh` to rebuild Go + regenerate bindings
> - Edited anything under `backend-go/` → re-run `dev.sh` to rebuild

**Frontend only** (browser preview, no Wails bindings):

```bash
cd frontend-react
npm run dev
# → http://localhost:5173
```

> Wails bindings (`ListDevices`, `GetDeviceInfo`, etc.) are no-ops in plain browser mode — they only work inside the Wails desktop window.

---

## Building for Production

### Full desktop app (recommended)

```bash
bash scripts/build.sh
```

Or manually:

```bash
# Step 1 — build frontend (outputs to desktop/frontend/dist/)
cd frontend-react
npm run build

# Step 2 — build desktop binary (embeds frontend dist + ADB binaries)
cd desktop
export PATH="$PATH:$(go env GOPATH)/bin"
wails build
```

Output: `desktop/build/bin/DroidScope` (macOS/Linux) or `desktop/build/bin/DroidScope.exe` (Windows)

---

### Backend only

```bash
cd backend-go
go build ./...
```

---

### Frontend only (static bundle)

```bash
cd frontend-react
npm run build
# Output: desktop/frontend/dist/
```

---

### Android SDK

```bash
cd android-sdk
./gradlew :sdk:assembleDebug     # debug AAR
./gradlew :sdk:assembleRelease   # release AAR
# Output: android-sdk/sdk/build/outputs/aar/
```

---

## Type Checking (no build)

```bash
# TypeScript
cd frontend-react
npx tsc -b --noEmit

# Go
cd backend-go && go build ./...
cd desktop && go build ./...
```

---

## Regenerating Wails JS Bindings

Run this after adding or changing any exported method on `App` in `desktop/app.go`:

```bash
cd desktop
export PATH="$PATH:$(go env GOPATH)/bin"
wails generate module
# Output: frontend-react/src/wailsjs/
```

---

## Project Structure

```
DroidScope/
├── desktop/                    ← Wails app (Go entry point)
│   ├── app.go                  ← Wails-bound methods (called from frontend)
│   ├── main.go                 ← App bootstrap
│   ├── wails.json              ← Wails config (frontend dir, dev server)
│   └── internal/adbembed/      ← ADB binary embedding + runtime extraction
│
├── backend-go/                 ← Go backend packages
│   ├── adb/                    ← ADB command wrapper
│   ├── device/                 ← Device manager + DeviceInfo fetcher
│   ├── logcat/                 ← (stub) Logcat streaming
│   ├── network/                ← (stub) Network inspector
│   ├── storage/                ← (stub) SharedPrefs, SQLite, files
│   ├── runtime/                ← (stub) Runtime config override
│   ├── session/                ← (stub) Session management
│   └── protocol/               ← Shared event types (Go structs)
│
├── frontend-react/             ← Vite + React + TypeScript
│   ├── src/
│   │   ├── wailsjs/            ← Auto-generated Wails bindings (do not edit)
│   │   ├── features/           ← Feature modules (devices, logcat, network…)
│   │   ├── components/         ← Shared UI components (layout, shadcn/ui)
│   │   ├── hooks/              ← Shared hooks (useActiveDevice)
│   │   ├── store/              ← Zustand global state
│   │   └── types/              ← Shared TypeScript types (protocol)
│   └── vite.config.ts          ← Build outputs to ../desktop/frontend/dist/
│
├── android-sdk/                ← Kotlin Android SDK (Gradle)
│   └── sdk/src/main/kotlin/dev/achmad/droidscope/
│
├── scripts/
│   ├── dev.sh                  ← Start full dev environment
│   ├── build.sh                ← Production build
│   └── download-adb.sh         ← Download ADB binaries for bundling
│
├── go.work                     ← Go workspace (links desktop + backend-go)
├── README.md                   ← Project overview and feature roadmap
├── TODO.md                     ← Implementation status
└── DEVELOPMENT.md              ← This file
```

---

## Key Conventions

### Adding a new Go method callable from the frontend

1. Add the method to `desktop/app.go` (must be exported, receiver `*App`)
2. Run `wails generate module` from `desktop/`
3. Import from `@/wailsjs/go/main/App` in React

### Adding a new backend-go package

1. Create the package under `backend-go/`
2. The `go.work` workspace + `replace` directive in `desktop/go.mod` handle local resolution — no publishing needed

### Active device scoping (all features)

- Import `useActiveDevice` from `@/hooks/use-active-device`
- Check `isMonitoring` before starting streams or polls
- Store per-device data in `deviceCache` via `patchDeviceCache(deviceId, data)` — never cleared on device switch
- Show `<NoDeviceSelected />` when `!isMonitoring`

---

## ADB Binary Bundling

For **local development** the app resolves ADB in this order:
1. Embedded binary in `desktop/internal/adbembed/bin/` (empty until `download-adb.sh` is run)
2. `$ANDROID_HOME/platform-tools/adb`
3. `adb` on `$PATH`

For **distribution builds** run `scripts/download-adb.sh` once before `wails build` to embed ADB for all platforms.
