# Local Development Setup Guide

This guide will help you set up the Go Payment Service for local testing and development.

## Prerequisites

Before you begin, ensure you have the following installed:

- **Go 1.21+** - [Download Go](https://golang.org/dl/)
- **PostgreSQL 12+** - [Download PostgreSQL](https://www.postgresql.org/download/)
- **Redis 6+** - [Download Redis](https://redis.io/download)
- **Git** - For cloning the repository

### Verify Installations

```bash
# Check Go version
go version

# Check PostgreSQL version
psql --version

# Check Redis version
redis-server --version
```

## Option 1: Quick Setup with Docker Compose (Recommended)

This is the easiest way to get started. Docker Compose will set up PostgreSQL, Redis, and the payment service automatically.

### Step 1: Update Docker Compose for PostgreSQL

The current `docker-compose.yml` uses MySQL, but the app uses PostgreSQL. Create a local version:

```bash
cd payment
```

Create `docker-compose.local.yml`:

```yaml
version: '3.8'

services:
  postgres:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=internet
      - POSTGRES_USER=payment_user
      - POSTGRES_PASSWORD=local_dev_password
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U payment_user"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5

volumes:
  postgres_data:
  redis_data:
```

### Step 2: Start Services

```bash
# Start PostgreSQL and Redis
docker-compose -f docker-compose.local.yml up -d

# Verify services are running
docker-compose -f docker-compose.local.yml ps
```

### Step 3: Configure Environment

```bash
# Copy example environment file
cp env.example .env

# Edit .env file with local settings
nano .env  # or use your preferred editor
```

Update `.env` with these values:

```env
# Database Configuration (PostgreSQL)
DB_HOST=localhost
DB_PORT=5432
DB_USER=payment_user
DB_PASSWORD=local_dev_password
DB_NAME=internet
DB_SSL_MODE=disable

# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0

# Server Configuration
SERVER_PORT=8080
SERVER_HOST=0.0.0.0
GIN_MODE=debug  # Use debug mode for local development

# JWT Configuration
JWT_SECRET=local_dev_jwt_secret_key_change_in_production_min_32_chars
JWT_EXPIRY_HOURS=24

# Logging (use text format for easier reading locally)
LOG_LEVEL=debug
LOG_FORMAT=text
```

### Step 4: Install Dependencies and Run

```bash
# Install Go dependencies
go mod download

# Run the application
go run main.go
```

The service should start on `http://localhost:8080`

## Option 2: Manual Setup (Without Docker)

If you prefer to install PostgreSQL and Redis directly on your system:

### Step 1: Install PostgreSQL

#### Windows
1. Download from [PostgreSQL Windows Installer](https://www.postgresql.org/download/windows/)
2. Run the installer and remember the password you set for the `postgres` user
3. PostgreSQL will be available on `localhost:5432`

#### macOS
```bash
# Using Homebrew
brew install postgresql@15
brew services start postgresql@15
```

#### Linux (Ubuntu/Debian)
```bash
sudo apt update
sudo apt install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo systemctl enable postgresql
```

### Step 2: Create Database and User

```bash
# Connect to PostgreSQL
psql -U postgres

# In PostgreSQL prompt:
CREATE DATABASE internet;
CREATE USER payment_user WITH PASSWORD 'local_dev_password';
ALTER ROLE payment_user SET client_encoding TO 'utf8';
ALTER ROLE payment_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE payment_user SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE internet TO payment_user;
\q
```

### Step 3: Install and Start Redis

#### Windows
1. Download from [Redis for Windows](https://github.com/microsoftarchive/redis/releases)
2. Or use WSL (Windows Subsystem for Linux)
3. Or use Docker: `docker run -d -p 6379:6379 redis:7-alpine`

#### macOS
```bash
brew install redis
brew services start redis
```

#### Linux (Ubuntu/Debian)
```bash
sudo apt install redis-server
sudo systemctl start redis-server
sudo systemctl enable redis-server
```

### Step 4: Verify Services

```bash
# Test PostgreSQL connection
psql -U payment_user -d internet -h localhost -c "SELECT version();"

# Test Redis connection
redis-cli ping
# Should return: PONG
```

### Step 5: Configure and Run

```bash
# Navigate to payment directory
cd payment

# Copy and configure .env file
cp env.example .env
# Edit .env with your local settings (see Option 1, Step 3)

# Install dependencies
go mod download

# Run the application
go run main.go
```

## Testing the Setup

### 1. Health Check

```bash
# Using curl
curl http://localhost:8080/health

# Using browser
# Open: http://localhost:8080/health
```

Expected response:
```json
{
  "status": "healthy",
  "timestamp": "2025-12-12T10:00:00Z"
}
```

### 2. Register a Test Client

```bash
curl -X POST http://localhost:8080/api/v1/clients/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test Company",
    "email": "test@example.com",
    "phone": "254712345678",
    "address": "Nairobi, Kenya",
    "username": "testuser",
    "password": "testpassword123"
  }'
```

### 3. Login

```bash
curl -X POST http://localhost:8080/api/v1/clients/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "testuser",
    "password": "testpassword123"
  }'
```

Save the returned `token` for authenticated requests.

### 4. Set Payment Credentials (Optional - for M-Pesa testing)

```bash
curl -X POST http://localhost:8080/api/v1/clients/credentials \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -d '{
    "provider": "mpesa",
    "consumer_key": "your_sandbox_consumer_key",
    "consumer_secret": "your_sandbox_consumer_secret",
    "short_code": "174379",
    "pass_key": "your_pass_key",
    "base_url": "https://sandbox.safaricom.co.ke",
    "callback_url": "http://localhost:8080/api/v1/callbacks/mpesa",
    "is_active": true
  }'
```

### 5. Create a Package

```bash
curl -X POST http://localhost:8080/api/v1/packages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -d '{
    "name": "Daily Basic",
    "description": "Basic daily internet package",
    "amount": 50.00,
    "currency": "KES",
    "speed": "10Mbps",
    "duration": "1 day",
    "is_active": true
  }'
```

### 6. Get Public Packages

```bash
curl http://localhost:8080/api/v1/packages/public?client_id=YOUR_CLIENT_UUID
```

## Development Tips

### Enable Debug Mode

In your `.env` file:
```env
GIN_MODE=debug
LOG_LEVEL=debug
LOG_FORMAT=text
```

This will:
- Show detailed request logs
- Enable Gin's debug mode (more verbose errors)
- Use text format instead of JSON for easier reading

### Hot Reload (Optional)

Install `air` for automatic reloading during development:

```bash
# Install air
go install github.com/cosmtrek/air@latest

# Run with hot reload
air
```

Create `.air.toml` in the payment directory:
```toml
root = "."
tmp_dir = "tmp"

[build]
  cmd = "go build -o ./tmp/main ."
  bin = "tmp/main"
  include_ext = ["go", "tpl", "tmpl", "html"]
  exclude_dir = ["assets", "tmp", "vendor"]
  include_dir = []
  exclude_regex = ["_test.go"]
  exclude_unchanged = false
  follow_symlink = false
  log = "build-errors.log"
  poll = false
  poll_interval = 0
  rerun = false
  rerun_delay = 500
  send_interrupt = false
  delay = 0
  stop_on_error = false

[color]
  app = ""
  build = "yellow"
  main = "magenta"
  runner = "green"
  watcher = "cyan"

[log]
  time = false
  main_only = false
```

### Database Migrations

The application automatically runs migrations on startup. To manually trigger:

```bash
go run main.go migrate
```

### View Logs

When running locally with `LOG_FORMAT=text`, logs will appear in the console. For JSON format, use a JSON viewer or parse with `jq`:

```bash
go run main.go 2>&1 | jq
```

## Troubleshooting

### Database Connection Issues

1. **Check PostgreSQL is running:**
   ```bash
   # Windows
   # Check Services app or:
   pg_ctl status
   
   # macOS/Linux
   sudo systemctl status postgresql
   ```

2. **Verify connection:**
   ```bash
   psql -U payment_user -d internet -h localhost
   ```

3. **Check .env file has correct credentials**

### Redis Connection Issues

1. **Check Redis is running:**
   ```bash
   redis-cli ping
   # Should return: PONG
   ```

2. **Check Redis port:**
   ```bash
   # Windows
   netstat -an | findstr 6379
   
   # macOS/Linux
   netstat -an | grep 6379
   ```

### Port Already in Use

If port 8080 is already in use:

1. Change `SERVER_PORT` in `.env`:
   ```env
   SERVER_PORT=8081
   ```

2. Or find and kill the process using port 8080:
   ```bash
   # Windows
   netstat -ano | findstr :8080
   taskkill /PID <PID> /F
   
   # macOS/Linux
   lsof -ti:8080 | xargs kill -9
   ```

### Go Module Issues

```bash
# Clean module cache
go clean -modcache

# Download dependencies again
go mod download

# Verify dependencies
go mod verify
```

## Next Steps

- Read the [API Documentation](docs/API.md)
- Check [Performance Testing Guide](docs/PERFORMANCE_TESTING.md)
- Review [Deployment Guide](DEPLOYMENT.md) for production setup

## Useful Commands

```bash
# Run tests
go test ./...

# Build binary
go build -o payment-service .

# Run with specific environment
GIN_MODE=debug go run main.go

# Check for updates
go list -u -m all

# Format code
go fmt ./...

# Run linter (if installed)
golangci-lint run
```

