#!/bin/bash
# iTechSmart Pulse Scanner — Linux
# Supports: Ubuntu, Debian, Fedora, CentOS, Arch, and more

set -e

PURPLE='\033[95m'
GREEN='\033[92m'
YELLOW='\033[93m'
RED='\033[91m'
BOLD='\033[1m'
END='\033[0m'

echo -e "${PURPLE}${BOLD}"
cat << 'BANNER'
  ██╗████████╗███████╗ ██████╗██╗  ██╗
  ██║╚══██╔══╝██╔════╝██╔════╝██║  ██║
  ██║   ██║   █████╗  ██║     ███████║
  ██║   ██║   ██╔══╝  ██║     ██╔══██║
  ██║   ██║   ███████╗╚██████╗██║  ██║
  ╚═╝   ╚═╝   ╚══════╝ ╚═════╝╚═╝  ╚═╝
  ███████╗███╗   ███╗ █████╗ ██████╗ ████████╗
  ██╔════╝████╗ ████║██╔══██╗██╔══██╗╚══██╔══╝
  ███████╗██╔████╔██║███████║██████╔╝   ██║
  ╚════██║██║╚██╔╝██║██╔══██║██╔══██╗   ██║
  ███████║██║ ╚═╝ ██║██║  ██║██║  ██║   ██║
  ╚══════╝╚═╝     ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝
BANNER
echo -e "${END}"
echo -e "  ${BOLD}iTechSmart Pulse — Linux Security Scanner${END}"
echo -e "  Powered by iTechSmart UAIO Platform"
echo "  ──────────────────────────────────────────"
echo ""

# Check Python
if ! command -v python3 &>/dev/null; then
    echo -e "  ${YELLOW}Installing Python3...${END}"
    if command -v apt-get &>/dev/null; then
        sudo apt-get install -y python3 python3-pip 2>/dev/null
    elif command -v yum &>/dev/null; then
        sudo yum install -y python3 python3-pip 2>/dev/null
    elif command -v dnf &>/dev/null; then
        sudo dnf install -y python3 python3-pip 2>/dev/null
    elif command -v pacman &>/dev/null; then
        sudo pacman -S --noconfirm python python-pip 2>/dev/null
    else
        echo -e "  ${RED}Please install Python3${END}"
        exit 1
    fi
fi

echo -e "  ${GREEN}+${END}  Python3 found"

# Download and run scanner
TMPFILE=$(mktemp /tmp/pulse_XXXXXX.py)

curl -sSL \
  "https://app.itechsmart.dev/download/pulse-mac-script" \
  -o "$TMPFILE" 2>/dev/null || \
wget -q \
  "https://app.itechsmart.dev/download/pulse-mac-script" \
  -O "$TMPFILE" 2>/dev/null

if [ -s "$TMPFILE" ]; then
    python3 "$TMPFILE"
else
    # Fallback: inline scanner
    echo -e "  ${YELLOW}!${END}  Download failed, running embedded scanner..."
    python3 << 'PYSCAN'
import sys, os, json, hashlib, platform, subprocess, socket
from datetime import datetime, timezone

PURPLE='\033[95m'; GREEN='\033[92m'; YELLOW='\033[93m'; RED='\033[91m'; BOLD='\033[1m'; END='\033[0m'

def ok(msg): print(f"  {GREEN}+{END}  {msg}")
def warn(msg): print(f"  {YELLOW}!{END}  {msg}")

print(f"\n  {PURPLE}{BOLD}Pulse{END} Security Scanner v1.1.1")
print(f"  {'_'*42}\n")

# System info
hostname = socket.gethostname()
ok(f"Host:  {hostname}")
ok(f"OS:    {platform.system()} {platform.machine()}")
ok(f"CPUs:  {os.cpu_count() or 0}")

# Security checks
checks = []
print(f"\n  {PURPLE}{BOLD}[2]{END} Running security checks...")

# Firewall (iptables/ufw)
try:
    r = subprocess.run(["ufw", "status"], capture_output=True, text=True, timeout=5)
    if "active" in r.stdout.lower():
        checks.append({"name": "Firewall", "status": "pass", "detail": "UFW active"})
    else:
        checks.append({"name": "Firewall", "status": "warn", "detail": "UFW inactive"})
except Exception:
    try:
        r = subprocess.run(["iptables", "-L", "-n"], capture_output=True, text=True, timeout=5)
        rules = len([l for l in r.stdout.split('\n') if l.strip() and not l.startswith('Chain') and not l.startswith('target')])
        checks.append({"name": "Firewall", "status": "pass" if rules > 0 else "warn", "detail": f"{rules} iptables rules"})
    except Exception:
        checks.append({"name": "Firewall", "status": "unknown", "detail": "Could not check"})

# Open ports
try:
    r = subprocess.run(["ss", "-tlnp"], capture_output=True, text=True, timeout=5)
    n = len([l for l in r.stdout.split('\n') if 'LISTEN' in l])
    checks.append({"name": "Open Ports", "status": "pass" if n < 30 else "warn", "detail": f"{n} listening"})
except Exception:
    checks.append({"name": "Open Ports", "status": "unknown", "detail": "Could not check"})

# Updates
try:
    r = subprocess.run(["apt", "list", "--upgradable"], capture_output=True, text=True, timeout=15)
    upgrades = len([l for l in r.stdout.split('\n') if '/' in l]) - 1
    checks.append({"name": "Updates", "status": "pass" if upgrades < 5 else "warn", "detail": f"{max(0, upgrades)} pending"})
except Exception:
    checks.append({"name": "Updates", "status": "unknown", "detail": "Could not check"})

# Permissions
try:
    r = subprocess.run(["find", "/etc", "-perm", "-o+w", "-type", "f"], capture_output=True, text=True, timeout=10)
    world_writable = len([l for l in r.stdout.strip().split('\n') if l])
    checks.append({"name": "File Permissions", "status": "pass" if world_writable < 3 else "warn", "detail": f"{world_writable} world-writable in /etc"})
except Exception:
    checks.append({"name": "File Permissions", "status": "unknown", "detail": "Could not check"})

for c in checks:
    (ok if c["status"] == "pass" else warn)(f"{c['name']}: {c['detail']}")

# Grade
passed = sum(1 for c in checks if c["status"] == "pass")
total = len(checks)
ratio = passed / total if total else 0
grade = "A" if ratio >= 0.9 else "B" if ratio >= 0.75 else "C" if ratio >= 0.6 else "D" if ratio >= 0.4 else "F"

# Receipt
scan = {"hostname": hostname, "os": f"{platform.system()} {platform.machine()}", "grade": grade,
        "checks_passed": passed, "checks_total": total, "checks": checks,
        "timestamp": datetime.now(timezone.utc).isoformat()}
receipt_hash = hashlib.sha256(json.dumps(scan, sort_keys=True).encode()).hexdigest()

gc = {**dict.fromkeys(["A","B"], GREEN), **dict.fromkeys(["C"], YELLOW), **dict.fromkeys(["D","F"], RED)}.get(grade, GREEN)
print(f"\n  {'='*40}\n")
print(f"  {BOLD}SCAN RESULTS{END}\n  {'_'*40}")
print(f"  Grade:    {gc}{BOLD} {grade} {END}")
print(f"  Passed:   {passed}/{total} checks")
print(f"  Host:     {hostname}")
print(f"\n  {BOLD}RECEIPT{END}\n  {'_'*40}")
print(f"  Hash:  {BOLD}{receipt_hash}{END}")
print(f"\n  Verify: {GREEN}{BOLD}https://itechsmart.dev/verify?hash={receipt_hash[:16]}{END}")
print(f"\n  {'='*40}\n")
print(f"  {GREEN}{BOLD}Scan complete!{END} Powered by {PURPLE}iTechSmart UAIO{END}\n")
PYSCAN
fi

rm -f "$TMPFILE"
