#!/bin/bash
# ================================================
#  SolveMate One-Click Installer for macOS
#  Downloads, installs, and auto-configures everything.
#  The extension will appear in Chrome automatically.
# ================================================

set -e

GREEN='\033[0;32m'
BOLD='\033[1m'
NC='\033[0m' # No Color

EXT_ID="liibdgofjdbmbcgllodpdbehlfhfpkal"
UPDATE_URL="https://www.solvemate.net/updates.xml"
DOWNLOAD_URL="https://www.solvemate.net/download"
INSTALL_DIR="$HOME/Library/Application Support/SolveMate"
EXT_DIR="$INSTALL_DIR/extension"

echo ""
echo "  ============================================="
echo "       SolveMate Extension Installer (Mac)"
echo "  ============================================="
echo ""
echo "  This will install SolveMate on your computer."
echo "  Chrome will load it automatically — no manual"
echo "  steps required."
echo ""
read -p "  Press Enter to start..." _dummy

# ── Step 1: Create install folder ──
echo ""
echo "  [1/4] Creating install folder..."
mkdir -p "$EXT_DIR"
echo "        Done: $INSTALL_DIR"

# ── Step 2: Download the extension ──
echo ""
echo "  [2/4] Downloading SolveMate extension..."
ZIP_PATH="/tmp/solvemate-extension.zip"
curl -fsSL "$DOWNLOAD_URL" -o "$ZIP_PATH"

if [ ! -f "$ZIP_PATH" ]; then
    echo ""
    echo "  ERROR: Download failed. Check your internet connection."
    echo "  You can try downloading manually from https://www.solvemate.net"
    exit 1
fi
echo "        Downloaded successfully!"

# ── Step 3: Extract the extension ──
echo ""
echo "  [3/4] Extracting files..."
# Remove old files first
rm -rf "$EXT_DIR"/*
unzip -qo "$ZIP_PATH" -d "$EXT_DIR"

if [ ! -f "$EXT_DIR/manifest.json" ]; then
    echo ""
    echo "  ERROR: Extraction failed."
    exit 1
fi
echo "        Extracted to $EXT_DIR"

# Clean up zip
rm -f "$ZIP_PATH"

# ── Step 4: Install via Chrome Enterprise Policy ──
echo ""
echo "  [4/4] Registering extension with Chrome..."

# On macOS, Chrome policies go in ~/Library/Preferences/ as a plist
# The ExtensionInstallForcelist policy tells Chrome to auto-install
PLIST_DIR="$HOME/Library/Preferences"
PLIST_FILE="$PLIST_DIR/com.google.Chrome.plist"

# Write the policy using defaults command
# Format: <extension_id>;<update_url>
POLICY_VALUE="${EXT_ID};${UPDATE_URL}"

# Check if the policy array already exists
EXISTING=$(defaults read com.google.Chrome ExtensionInstallForcelist 2>/dev/null || echo "")

if echo "$EXISTING" | grep -q "$EXT_ID"; then
    echo "        Extension already registered!"
else
    # Add to the forcelist (create if needed)
    defaults write com.google.Chrome ExtensionInstallForcelist -array-add "$POLICY_VALUE" 2>/dev/null || \
    defaults write com.google.Chrome ExtensionInstallForcelist -array "$POLICY_VALUE"
    echo "        Extension registered with Chrome policy!"
fi

# Set up native messaging host for auto-updates if Node.js is available
if command -v node &>/dev/null; then
    echo ""
    echo "  Setting up auto-updater..."
    UPDATER_DIR="$EXT_DIR/updater"
    mkdir -p "$UPDATER_DIR"

    NODE_PATH=$(which node)

    # Create the updater script (cross-platform Node.js)
    cat > "$UPDATER_DIR/solvemate_updater.js" << 'JSEOF'
// SolveMate Auto-Updater - Native Messaging Host
const https = require('https'); const http = require('http');
const fs = require('fs'); const path = require('path');
const os = require('os'); const { execSync } = require('child_process');
const DOWNLOAD_URL = 'https://www.solvemate.net/download';
function readMsg() { return new Promise(r => { let hdr = false, len = 0, chunks = [], got = 0;
  process.stdin.on('readable', function f() { if (!hdr) { const h = process.stdin.read(4);
    if (!h) return; len = h.readUInt32LE(0); hdr = true; }
    if (hdr) { const c = process.stdin.read(len - got); if (!c) return;
      chunks.push(c); got += c.length; if (got >= len) { process.stdin.removeListener('readable', f);
        r(JSON.parse(Buffer.concat(chunks).toString())); } } }); }); }
function sendMsg(m) { const b = Buffer.from(JSON.stringify(m)); const h = Buffer.alloc(4);
  h.writeUInt32LE(b.length); process.stdout.write(h); process.stdout.write(b); }
function dl(url, dest) { return new Promise((ok, fail) => {
  (url.startsWith('https') ? https : http).get(url, r => {
    if (r.statusCode >= 300 && r.statusCode < 400 && r.headers.location)
      { return dl(r.headers.location, dest).then(ok).catch(fail); }
    if (r.statusCode !== 200) return fail(new Error('HTTP ' + r.statusCode));
    const f = fs.createWriteStream(dest); r.pipe(f);
    f.on('finish', () => { f.close(); ok(); });
  }).on('error', fail); }); }
async function main() { try { const msg = await readMsg();
  const extDir = path.resolve(__dirname, '..' );
  if (msg.action === 'check') { sendMsg({ success: true, message: 'ready', extensionDir: extDir }); return; }
  if (msg.action === 'update') { const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'sm-'));
    const zp = path.join(tmp, 'ext.zip'); const ex = path.join(tmp, 'ex');
    await dl(DOWNLOAD_URL, zp); fs.mkdirSync(ex, { recursive: true });
    if (process.platform === 'win32') {
      execSync('powershell -Command "Expand-Archive -Path \'' + zp + '\' -DestinationPath \'' + ex + '\' -Force"', { windowsHide: true });
    } else {
      execSync('unzip -qo "' + zp + '" -d "' + ex + '"');
    }
    if (!fs.existsSync(path.join(ex, 'manifest.json'))) { sendMsg({ success: false, error: 'Bad zip' }); return; }
    for (const f of fs.readdirSync(ex)) { if (f === 'updater') continue;
      const s = path.join(ex, f), d = path.join(extDir, f);
      if (fs.statSync(s).isDirectory()) { if (fs.existsSync(d)) fs.rmSync(d, { recursive: true, force: true });
        fs.cpSync(s, d, { recursive: true }); } else fs.copyFileSync(s, d); }
    try { fs.rmSync(tmp, { recursive: true, force: true }); } catch(_) {}
    sendMsg({ success: true, message: 'Updated', extensionDir: extDir }); }
  else sendMsg({ success: false, error: 'Unknown action' });
} catch(e) { try { sendMsg({ success: false, error: e.message }); } catch(_){} } } main();
JSEOF

    # Create native messaging manifest
    NM_DIR="$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts"
    mkdir -p "$NM_DIR"

    cat > "$NM_DIR/com.solvemate.updater.json" << NMEOF
{
  "name": "com.solvemate.updater",
  "description": "SolveMate Auto-Updater",
  "path": "$UPDATER_DIR/solvemate_updater_host.sh",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://${EXT_ID}/"
  ]
}
NMEOF

    # Create shell wrapper for native messaging
    cat > "$UPDATER_DIR/solvemate_updater_host.sh" << SHEOF
#!/bin/bash
"$NODE_PATH" "$UPDATER_DIR/solvemate_updater.js"
SHEOF
    chmod +x "$UPDATER_DIR/solvemate_updater_host.sh"

    echo "        Auto-updater configured!"
fi

echo ""
echo "  ============================================="
echo "       Installation Complete!"
echo "  ============================================="
echo ""
echo "  Restarting Chrome to activate SolveMate..."
echo "  (Your tabs will be restored automatically)"
echo ""

# Close Chrome gracefully, wait, then reopen
if pgrep -x "Google Chrome" >/dev/null 2>&1; then
    osascript -e 'quit app "Google Chrome"' 2>/dev/null
    sleep 2
fi

# Reopen Chrome to McGraw Hill (picks up the policy on launch)
open -a "Google Chrome" "https://connect.mheducation.com" 2>/dev/null || \
open "https://connect.mheducation.com"

echo "  Chrome has been restarted with SolveMate installed!"
echo ""
echo "  You'll see \"Managed by your organization\" in"
echo "  chrome://extensions — that's normal and means"
echo "  the auto-install is working."
echo ""
echo "  Done! You can close this terminal window."
