# Legacy Code Cleanup & Modernization Plan

## Overview

This document identifies outdated code, redundant systems, and performance bottlenecks in EasyStream that should be removed or refactored to create a modern, efficient streaming platform.

## Table of Contents

1. [Critical Removals](#critical-removals)
2. [Authentication System Cleanup](#authentication-system-cleanup)
3. [Database Query Optimization](#database-query-optimization)
4. [Frontend JavaScript Modernization](#frontend-javascript-modernization)
5. [File Structure Reorganization](#file-structure-reorganization)
6. [Performance Optimizations](#performance-optimizations)
7. [Migration Checklist](#migration-checklist)

---

## Critical Removals

### 1. Duplicate Authentication Systems

**Problem:** Multiple authentication systems exist, causing confusion and security risks.

**Files to Remove/Consolidate:**

```
REMOVE:
- f_core/f_classes/class.login.php (Old VLogin class)
- f_core/f_classes/class.session.php (Redundant with VAuth)
- Any references to VLogin in other files

KEEP:
- f_core/f_classes/class.auth.php (VAuth - Modern system)
```

**Action Plan:**
1. Search codebase for `VLogin` references
2. Replace with `VAuth::getInstance()`
3. Update all login forms to use VAuth
4. Remove class.login.php entirely

**Command to find VLogin usage:**
```bash
grep -r "VLogin" f_core/ f_modules/ *.php
```

### 2. Legacy Database Classes

**Problem:** Multiple database wrapper classes causing overhead.

**Files to Audit:**
```
f_core/f_classes/class.database.php - Keep (ADOdb wrapper)
f_core/f_classes/db*.php - Review for redundancy
```

**Action:** Ensure all code uses `VDatabase::getInstance()` and remove any custom DB wrappers.

### 3. Obsolete jQuery Plugins

**Problem:** Old jQuery plugins add bloat and security vulnerabilities.

**Files to Remove:**
```
f_scripts/be/js/init1.min.js - Contains jquery.form plugin (outdated)
f_scripts/*/jquery.*.min.js - Review each for necessity
```

**Replace With:**
- Native FormData API
- Fetch API
- Modern ES6+ code

### 4. Inline JavaScript in PHP Files

**Problem:** JavaScript mixed with PHP makes maintenance difficult.

**Action:**
1. Extract all `<script>` tags from PHP files
2. Move to dedicated .js files
3. Use data attributes for configuration
4. Use modern module pattern

**Example Files to Clean:**
```
browse.php - Contains inline JS
profile.php - Contains inline JS
upload.php - Contains inline JS
```

---

## Authentication System Cleanup

### Current State: 3 Auth Methods

1. **Old VLogin** (deprecated)
2. **VSession** (redundant)
3. **VAuth** (modern, keep this)

### Cleanup Steps

#### Step 1: Find All VLogin Usage

```bash
# Find files using VLogin
grep -r "VLogin" --include="*.php" .

# Find session_start calls (should be in VAuth only)
grep -r "session_start()" --include="*.php" .
```

#### Step 2: Update All References

**Before:**
```php
$login = new VLogin();
$login->doLogin($username, $password);
if ($login->isLoggedIn()) {
    // ...
}
```

**After:**
```php
$auth = VAuth::getInstance();
$result = $auth->login($identifier, $password);
if ($auth->isAuthenticated()) {
    // ...
}
```

#### Step 3: Remove Old Files

```bash
# After migrating all code:
rm f_core/f_classes/class.login.php
rm f_core/f_classes/class.session.php
```

### Session Management Consolidation

**Keep Only:**
- VAuth for all authentication
- VSession for session utilities (if lightweight)

**Or:** Merge VSession functionality into VAuth

---

## Database Query Optimization

### Problem: N+1 Query Issues

**Current Issue:**
```php
// BAD: N+1 queries
$videos = $db->execute("SELECT * FROM db_videofiles");
while (!$videos->EOF) {
    $user = $db->execute("SELECT * FROM db_users WHERE usr_id = ?", [$videos->fields['usr_id']]);
    // This runs once per video!
}
```

**Solution:**
```php
// GOOD: Single query with JOIN
$sql = "SELECT v.*, u.usr_id, u.usr_user, u.usr_dname, u.usr_avatar
        FROM db_videofiles v
        LEFT JOIN db_users u ON v.usr_id = u.usr_id
        WHERE v.approved = 1";
$videos = $db->execute($sql);
```

### Remove Unnecessary Database Calls

#### 1. Count Queries in Loops

**Bad:**
```php
foreach ($videos as $video) {
    $commentCount = $db->singleFieldValue("SELECT COUNT(*) FROM db_comments WHERE file_key = ?", [$video['file_key']]);
}
```

**Good:**
```php
// Get all counts in one query
$sql = "SELECT file_key, COUNT(*) as comment_count
        FROM db_comments
        WHERE file_key IN (?)
        GROUP BY file_key";
```

#### 2. Redundant Existence Checks

**Bad:**
```php
// Check if exists
$exists = $db->execute("SELECT COUNT(*) FROM db_users WHERE usr_id = ?", [$userId]);
if ($exists->fields[0] > 0) {
    // Then fetch the user
    $user = $db->execute("SELECT * FROM db_users WHERE usr_id = ?", [$userId]);
}
```

**Good:**
```php
// Just fetch directly, check if result is empty
$user = $db->execute("SELECT * FROM db_users WHERE usr_id = ?", [$userId]);
if ($user && $user->RecordCount() > 0) {
    // Use user data
}
```

### Add Database Indexes

Critical indexes to add:

```sql
-- Video queries
CREATE INDEX idx_videofiles_approved_privacy ON db_videofiles(approved, privacy);
CREATE INDEX idx_videofiles_usr_id ON db_videofiles(usr_id);
CREATE INDEX idx_videofiles_upload_date ON db_videofiles(upload_date);
CREATE INDEX idx_videofiles_file_views ON db_videofiles(file_views);

-- Comment queries
CREATE INDEX idx_comments_file_key ON db_comments(file_key);
CREATE INDEX idx_comments_parent_id ON db_comments(parent_id);
CREATE INDEX idx_comments_usr_id ON db_comments(usr_id);

-- Subscription queries
CREATE INDEX idx_subscriptions_usr_id ON db_subscriptions(usr_id);
CREATE INDEX idx_subscriptions_channel_id ON db_subscriptions(channel_id);

-- Like queries
CREATE INDEX idx_likes_file_key_type ON db_likes(file_key, like_type);
CREATE INDEX idx_likes_usr_id ON db_likes(usr_id);

-- Session queries
CREATE INDEX idx_sessions_user_id ON db_sessions(user_id);
CREATE INDEX idx_sessions_expires_at ON db_sessions(expires_at);
```

---

## Frontend JavaScript Modernization

### Remove jQuery Dependency

jQuery is heavy (87KB minified) and no longer necessary.

#### Migration Strategy

**Phase 1: Utility Functions**

Create `f_scripts/fe/js/utils.js`:

```javascript
// Modern replacements for jQuery
const $ = {
  // $(selector) -> document.querySelectorAll
  select: (selector) => document.querySelectorAll(selector),
  selectOne: (selector) => document.querySelector(selector),

  // $.ajax -> fetch
  ajax: async (url, options = {}) => {
    const response = await fetch(url, options);
    return response.json();
  },

  // $.get -> fetch
  get: async (url) => {
    const response = await fetch(url);
    return response.json();
  },

  // $.post -> fetch
  post: async (url, data) => {
    const response = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    });
    return response.json();
  },

  // $(element).addClass/removeClass
  addClass: (el, className) => el.classList.add(className),
  removeClass: (el, className) => el.classList.remove(className),
  toggleClass: (el, className) => el.classList.toggle(className),

  // $(element).show/hide
  show: (el) => el.style.display = '',
  hide: (el) => el.style.display = 'none',

  // $(element).on
  on: (el, event, handler) => el.addEventListener(event, handler),
  off: (el, event, handler) => el.removeEventListener(event, handler),

  // $.each -> Array.forEach
  each: (arr, callback) => Array.from(arr).forEach(callback)
};
```

**Phase 2: Replace jQuery Usage**

**Before:**
```javascript
jQuery(document).ready(function() {
  jQuery('.button').click(function() {
    jQuery(this).addClass('active');
  });
});
```

**After:**
```javascript
document.addEventListener('DOMContentLoaded', () => {
  document.querySelectorAll('.button').forEach(btn => {
    btn.addEventListener('click', () => {
      btn.classList.add('active');
    });
  });
});
```

Or using event delegation (more efficient):
```javascript
document.addEventListener('click', (e) => {
  if (e.target.classList.contains('button')) {
    e.target.classList.add('active');
  }
});
```

### Files to Modernize

Priority order:

1. **High Priority (User-facing)**
   - `browse.init.js` - Video browsing
   - `login.init.js` - Authentication
   - `jquery.init.js` - Global utilities

2. **Medium Priority**
   - `files.init.js` - File management
   - `channels.init.js` - Channel features
   - `subdashboard.js` - Dashboard

3. **Low Priority**
   - Backend admin files
   - Analytics dashboards

### Remove Unused Libraries

Audit and remove:

```
f_scripts/lib/
├── jquery.old.js - Remove if exists
├── bootstrap.v2.js - If using v4+, remove v2
├── moment.js - Use native Date if possible
├── lodash.js - Use native ES6 methods
└── underscore.js - Redundant with lodash
```

---

## File Structure Reorganization

### Current Issues

1. **Flat file structure** - Hard to navigate
2. **Mixed concerns** - Frontend/backend not separated
3. **Redundant files** - Multiple versions of same functionality

### Proposed Structure

```
api/                          # All API endpoints (CLEAN)
├── auth.php
├── videos.php
├── user.php
├── comments.php
├── subscriptions.php
└── cors.config.php

f_core/                       # Core backend classes (KEEP CLEAN)
├── config.core.php           # Main config
├── config.database.php       # DB config
├── f_classes/                # Core classes
│   ├── class.auth.php        # KEEP
│   ├── class.database.php    # KEEP
│   ├── class.security.php    # KEEP
│   ├── class.logger.php      # KEEP
│   ├── class.rbac.php        # KEEP
│   ├── class.middleware.php  # KEEP
│   └── [REMOVE OLD CLASSES]
└── f_functions/              # Utility functions
    ├── functions.security.php
    └── functions.rbac.php

f_scripts/
├── fe/                       # Frontend only
│   ├── js/
│   │   ├── api-helper.js     # MODERN API client
│   │   ├── utils.js          # Native JS utilities
│   │   └── [page-specific].js
│   ├── css/
│   └── img/
└── be/                       # Backend admin
    └── js/

f_modules/                    # Feature modules
├── m_frontend/               # User-facing features
└── m_backend/                # Admin features

docs/                         # Documentation
├── API_DOCUMENTATION.md
├── FRONTEND_BACKEND_INTEGRATION_GUIDE.md
└── LEGACY_CODE_CLEANUP_PLAN.md

[root]                        # Page entry points
├── index.php
├── browse.php
├── profile.php
└── ...
```

### Files to Remove

```bash
# Find duplicate/old files
find . -name "*.old.php"
find . -name "*.backup.php"
find . -name "*_old.*"
find . -name "*_backup.*"

# Remove after verification
rm [files]
```

---

## Performance Optimizations

### 1. Implement Lazy Loading

**Videos/Images:**

```javascript
// Use Intersection Observer instead of scroll events
const lazyLoadObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      img.classList.remove('lazy');
      lazyLoadObserver.unobserve(img);
    }
  });
});

document.querySelectorAll('img.lazy').forEach(img => {
  lazyLoadObserver.observe(img);
});
```

### 2. Implement Caching

**Backend (PHP):**

```php
// Use Redis/Memcached for session storage (already configured)
// Add query result caching

class VCache {
    private static $redis;

    public static function get($key) {
        if (!self::$redis) {
            self::$redis = new Redis();
            self::$redis->connect('127.0.0.1', 6379);
        }
        return self::$redis->get($key);
    }

    public static function set($key, $value, $ttl = 3600) {
        if (!self::$redis) {
            self::$redis = new Redis();
            self::$redis->connect('127.0.0.1', 6379);
        }
        return self::$redis->setex($key, $ttl, serialize($value));
    }
}

// Usage
$cacheKey = "videos:popular:page:{$page}";
$videos = VCache::get($cacheKey);

if (!$videos) {
    $videos = $db->execute($sql, $params);
    VCache::set($cacheKey, $videos->GetArray(), 300); // 5 min cache
}
```

**Frontend:**

```javascript
// Cache API responses in memory
class APICache {
  constructor(ttl = 60000) { // 1 minute default
    this.cache = new Map();
    this.ttl = ttl;
  }

  get(key) {
    const item = this.cache.get(key);
    if (!item) return null;

    if (Date.now() > item.expires) {
      this.cache.delete(key);
      return null;
    }

    return item.data;
  }

  set(key, data) {
    this.cache.set(key, {
      data,
      expires: Date.now() + this.ttl
    });
  }

  clear() {
    this.cache.clear();
  }
}

// Add to api-helper.js
const apiCache = new APICache();

// In request method:
const cacheKey = `${endpoint}:${JSON.stringify(params)}`;
const cached = apiCache.get(cacheKey);
if (cached && config.cache) {
  return cached;
}

// After successful request:
if (config.cache) {
  apiCache.set(cacheKey, data);
}
```

### 3. Optimize Database Queries

**Use Prepared Statement Caching:**

```php
// In VDatabase class
private $stmtCache = [];

public function execute($sql, $params = []) {
    $cacheKey = md5($sql);

    if (!isset($this->stmtCache[$cacheKey])) {
        $this->stmtCache[$cacheKey] = $this->connection->Prepare($sql);
    }

    return $this->connection->Execute($this->stmtCache[$cacheKey], $params);
}
```

### 4. Minify and Bundle Assets

**Create build process:**

```json
// package.json
{
  "scripts": {
    "build:js": "esbuild f_scripts/fe/js/**/*.js --bundle --minify --outdir=f_scripts/fe/dist/js",
    "build:css": "postcss f_scripts/fe/css/**/*.css --dir f_scripts/fe/dist/css --use cssnano",
    "build": "npm run build:js && npm run build:css",
    "watch": "npm run build -- --watch"
  }
}
```

### 5. Implement Code Splitting

Split JavaScript into chunks:

```javascript
// Load features on demand
async function loadVideoPlayer() {
  const { VideoPlayer } = await import('./video-player.js');
  return new VideoPlayer();
}

// Only load when needed
document.querySelector('.video-container').addEventListener('click', async () => {
  const player = await loadVideoPlayer();
  player.play();
}, { once: true });
```

### 6. Remove Render-Blocking Resources

**Move scripts to end of body:**

```html
<!-- Before: -->
<head>
  <script src="jquery.js"></script>
  <script src="app.js"></script>
</head>

<!-- After: -->
<body>
  <!-- content -->
  <script src="app.js" defer></script>
</body>
```

Or use `async` for independent scripts:

```html
<script src="analytics.js" async></script>
```

---

## Migration Checklist

### Phase 1: Remove Duplicate Auth Systems
- [ ] Find all VLogin references
- [ ] Replace with VAuth
- [ ] Test authentication flows
- [ ] Remove class.login.php
- [ ] Remove class.session.php (if redundant)
- [ ] Update documentation

### Phase 2: Database Optimization
- [ ] Add missing indexes
- [ ] Audit for N+1 queries
- [ ] Implement query caching
- [ ] Use JOINs instead of separate queries
- [ ] Enable prepared statement caching
- [ ] Monitor slow query log

### Phase 3: Frontend Modernization
- [ ] Create native JS utility library
- [ ] Migrate browse.init.js to modern JS
- [ ] Migrate login.init.js to modern JS
- [ ] Migrate jquery.init.js to modern JS
- [ ] Remove jQuery dependency
- [ ] Test all user interactions
- [ ] Update build process

### Phase 4: File Cleanup
- [ ] Remove obsolete files (.old, .backup)
- [ ] Reorganize file structure
- [ ] Remove unused libraries
- [ ] Clean up inline JavaScript
- [ ] Move JS to external files

### Phase 5: Performance Optimization
- [ ] Implement lazy loading for images
- [ ] Add Redis caching for queries
- [ ] Enable browser caching headers
- [ ] Minify and bundle assets
- [ ] Implement code splitting
- [ ] Add service worker for offline support (optional)

### Phase 6: Testing & Validation
- [ ] Load test with Apache Bench
- [ ] Profile with Chrome DevTools
- [ ] Check for memory leaks
- [ ] Verify all features work
- [ ] Test on slow connections (throttling)
- [ ] Mobile device testing

---

## Performance Metrics to Track

### Before Cleanup

Measure these metrics before starting:

```bash
# Page load time
curl -o /dev/null -s -w 'Total: %{time_total}s\n' http://localhost/

# Time to first byte
curl -o /dev/null -s -w 'TTFB: %{time_starttransfer}s\n' http://localhost/

# Database query count (add logging)
grep "SELECT" /var/log/mysql/query.log | wc -l
```

### After Cleanup - Target Metrics

- Page load time: < 2 seconds
- Time to first byte: < 500ms
- Total JavaScript size: < 200KB
- Database queries per page: < 10
- Memory usage: < 128MB per request

---

## Resource Savings Estimate

### Expected Improvements

| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| Page Load Time | 4-6s | 1-2s | 70% faster |
| JavaScript Size | 500KB | 150KB | 70% smaller |
| Database Queries | 30-50 | 5-10 | 80% fewer |
| Memory per Request | 256MB | 64MB | 75% less |
| Server Requests | 40+ | 15-20 | 60% fewer |

### Cost Savings

For a platform with 10,000 daily active users:

- **Server costs**: 50% reduction (fewer resources needed)
- **Bandwidth**: 60% reduction (smaller assets)
- **Database load**: 75% reduction (fewer queries, better caching)

---

## Next Steps

1. **Backup everything** before making changes
2. **Start with authentication** cleanup (lowest risk)
3. **Test thoroughly** after each phase
4. **Monitor performance** metrics
5. **Document changes** as you go

---

**Created:** January 2025
**Status:** Planning Phase
