#!/usr/bin/env bash
# install-curlai.sh
# Installer for Curl Ai project
# Creates project directory under ~/.git/curlai
# Initializes a git repo, creates python package layout, virtualenv,
# helper scripts in ~/bin, sample tests, README, LICENSE, and performs initial commit.
# Written to be idempotent and safe for Debian/Ubuntu (non-destructive checks).

set -euo pipefail
IFS=$'\n\t'

# -----------------------------
# Configuration (edit if needed)
# -----------------------------
PROJECT_BASE="$HOME/.git"
PROJECT_NAME="curlai"
PROJECT_DIR="$PROJECT_BASE/$PROJECT_NAME"
BIN_DIR="$HOME/bin"                  # user bin directory for helper scripts
PYTHON_BIN="python3"                 # python executable to use
VENV_DIR="$PROJECT_DIR/.venv"        # virtualenv location
GIT_NAME="REDACTED"                  # git author name used for initial commit
GIT_EMAIL="${GIT_NAME}@example.local"
VERSION="v1.0"
PROFILE_URL="https://x.com/BayouCityBum"
LICENSE_TYPE="MIT"

# -----------------------------
# Helpers
# -----------------------------
info() { printf "[INFO] %s\n" "$*"; }
err()  { printf "[ERROR] %s\n" "$*" >&2; }

# Ensure ~/bin exists and is on PATH for this script's session
mkdir -p "$BIN_DIR"
if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then
  export PATH="$BIN_DIR:$PATH"
  info "Added $BIN_DIR to PATH for this session. Add to your shell rc to persist."
fi

# -----------------------------
# Pre-flight: required tools
# -----------------------------
need_cmds=(git $PYTHON_BIN pip3)
missing=()
for cmd in "${need_cmds[@]}"; do
  if ! command -v "$cmd" >/dev/null 2>&1; then
    missing+=("$cmd")
  fi
done

if (( ${#missing[@]} > 0 )); then
  info "Missing commands: ${missing[*]}"
  # Try to install via apt-get if available
  if command -v apt-get >/dev/null 2>&1; then
    info "Attempting to install missing packages with apt-get (requires sudo)."
    sudo apt-get update -y
    sudo apt-get install -y git python3 python3-venv python3-pip || {
      err "Automatic install failed. Please install: ${missing[*]} and re-run this script.";
      exit 1
    }
  else
    err "Non-interactive installer can't install missing tools on this platform. Please install: ${missing[*]}"
    exit 1
  fi
fi

# -----------------------------
# Create project directories
# -----------------------------
info "Creating project directories under: $PROJECT_DIR"
mkdir -p "$PROJECT_DIR"
mkdir -p "$PROJECT_DIR/src/$PROJECT_NAME"     # package sources
mkdir -p "$PROJECT_DIR/tests"
mkdir -p "$PROJECT_DIR/docs"
mkdir -p "$PROJECT_DIR/examples"
mkdir -p "$PROJECT_DIR/logs"
mkdir -p "$PROJECT_DIR/assets"

# -----------------------------
# Create README.md
# -----------------------------
cat > "$PROJECT_DIR/README.md" <<'README'
# Curl Ai

Project: Curl Ai

Author: REDACTED
Profile: https://x.com/BayouCityBum
Version: v1.0

This repository contains a lightweight Python-based CLI/web helper for working with cURL-style workflows and integrations with small local LLM tooling.

Folders created by the installer:
- src/: Python package source
- tests/: pytest tests
- docs/: documentation and notes
- examples/: runnable examples
- logs/: runtime logs
- assets/: sample assets (images, thumbnails)

How to use:
1. Source virtualenv: `source .venv/bin/activate`
2. Install dependencies: `pip install -r requirements.txt` (installer already runs this)
3. Run: `./run.sh` or `bin/run-curlai.sh`

README

# -----------------------------
# Create LICENSE (MIT)
# -----------------------------
cat > "$PROJECT_DIR/LICENSE" <<'LICENSE'
MIT License

Copyright (c) $(date +%Y) REDACTED

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

LICENSE

# -----------------------------
# .gitignore
# -----------------------------
cat > "$PROJECT_DIR/.gitignore" <<'.GITIGNORE'
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# Virtual environment
.venv/

# Distribution / packaging
build/
dist/
*.egg-info/

# Logs
logs/
*.log

# System files
.DS_Store
.GITIGNORE

# -----------------------------
# pyproject.toml and setup.cfg
# -----------------------------
cat > "$PROJECT_DIR/pyproject.toml" <<'PYPROJECT'
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "curlai"
version = "1.0.0"
description = "Curl Ai - helper tools around curl workflows and LLM integrations"
authors = [ {name = "REDACTED", url = "https://x.com/BayouCityBum"} ]
readme = "README.md"
license = {text = "MIT"}
dependencies = [ ]

PYPROJECT

# -----------------------------
# requirements.txt
# -----------------------------
cat > "$PROJECT_DIR/requirements.txt" <<'REQS'
# Pin lightweight dependencies for now; update as needed
requests>=2.28
flask>=2.2
pytest>=7.0
yt-dlp>=2023.12.1
REQS

# -----------------------------
# Create sample python package files
# -----------------------------
PKG_DIR="$PROJECT_DIR/src/$PROJECT_NAME"

# __init__.py: package metadata and version
cat > "$PKG_DIR/__init__.py" <<'PYINIT'
"""
Curl Ai package initializer.
Contains package version, metadata and the public API surface.
"""

# Semantic version (kept in sync with installer VERSION variable)
__version__ = "1.0.0"

# Basic metadata
__author__ = "REDACTED"
__profile__ = "https://x.com/BayouCityBum"

# Export primary entrypoints
from .main import main  # re-export main for direct package execution

PYINIT

# main.py: simple CLI entrypoint with detailed comments
cat > "$PKG_DIR/main.py" <<'MAIN'
"""
Main module for Curl Ai.
Provides a tiny CLI and web entrypoint for demonstration.
"""
import argparse
import os
import sys

# Import local utilities (kept minimal and well-commented)
from . import __version__
from .utils import run_shell, download_url


def cli(argv=None):
    """Parse command-line arguments and dispatch commands.

    Args:
        argv (list|None): list of CLI args (for testing). If None, uses sys.argv[1:]
    Returns:
        int: exit code
    """
    parser = argparse.ArgumentParser(prog="curlai", description="Curl Ai CLI")
    parser.add_argument("--version", action="store_true", help="print version and exit")
    parser.add_argument("--fetch", metavar="URL", help="download a URL via requests")

    args = parser.parse_args(argv)

    if args.version:
        print(f"curlai {__version__}")
        return 0

    if args.fetch:
        out = download_url(args.fetch)
        print(out[:100] + "..." if len(out) > 100 else out)
        return 0

    parser.print_help()
    return 2


def main():
    """Main program entry used when running as module: python -m curlai
    Keep main minimal so unit tests can import cli() directly.
    """
    raise SystemExit(cli())

# Allow execution as a script
if __name__ == "__main__":
    main()

MAIN

# utils.py: helper functions with verbose comments
cat > "$PKG_DIR/utils.py" <<'UTILS'
"""
Utility functions used by Curl Ai.
All functions are small, explicit, and well-commented for learning.
"""
import subprocess
import requests


def run_shell(cmd, timeout=30):
    """Run a shell command and return stdout.

    Args:
        cmd (list|str): command to run (if list, recommended to avoid shell=True)
        timeout (int): seconds before timeout
    Returns:
        str: stdout of command
    Raises:
        subprocess.CalledProcessError on non-zero exit
    """
    if isinstance(cmd, str):
        cmd = cmd.split()
    result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=timeout)
    result.check_returncode()  # will raise CalledProcessError if exit != 0
    return result.stdout


def download_url(url, timeout=15):
    """Download the supplied URL and return text.
    This is a small wrapper around requests.get with basic error handling.
    """
    r = requests.get(url, timeout=timeout)
    r.raise_for_status()
    return r.text

UTILS

# -----------------------------
# Example script in examples/
# -----------------------------
cat > "$PROJECT_DIR/examples/demo_fetch.py" <<'DEMO'
"""
Example demonstrating using the curlai package to fetch a URL.
Run: python examples/demo_fetch.py
"""
from src.curlai.utils import download_url

if __name__ == "__main__":
    print(download_url("https://httpbin.org/get")[:300])

DEMO

# -----------------------------
# Tests (pytest)
# -----------------------------
cat > "$PROJECT_DIR/tests/test_basic.py" <<'TEST'
"""
Basic unit tests for the curlai package.
These are intentionally simple to verify package import and basic functions.
"""
import importlib


def test_import_main():
    # Ensure package imports successfully
    mod = importlib.import_module('src.curlai')
    assert hasattr(mod, '__version__')


def test_utils_download(monkeypatch):
    # Sanity test for download_url using monkeypatch to avoid network
    import src.curlai.utils as utils

    class DummyResp:
        status_code = 200
        text = 'ok'
        def raise_for_status(self):
            return None

    def fake_get(url, timeout=0):
        return DummyResp()

    import requests
    monkeypatch.setattr(requests, 'get', fake_get)
    assert utils.download_url('http://example') == 'ok'

TEST

# -----------------------------
# Create simple runner and helper scripts in project root and ~/bin
# -----------------------------
RUN_SH="$PROJECT_DIR/run.sh"
cat > "$RUN_SH" <<'RUN'
#!/usr/bin/env bash
# run.sh - run the curlai CLI inside the project's venv
# This script activates the venv (if present) and executes the curlai package
set -euo pipefail
source "$(dirname "$0")/.venv/bin/activate" || true
python -m src.curlai.main "$@"
RUN
chmod +x "$RUN_SH"

# bin/run-curlai.sh: global helper in ~/bin to run the project from anywhere
BIN_RUN="$BIN_DIR/run-curlai.sh"
cat > "$BIN_RUN" <<'BINRUN'
#!/usr/bin/env bash
# run-curlai.sh - global helper to locate the curlai project and run it
# Locates project under ~/.git/curlai by default
set -euo pipefail
PROJECT_DIR="$HOME/.git/curlai"
if [[ ! -d "$PROJECT_DIR" ]]; then
  echo "Project not found at $PROJECT_DIR" >&2
  exit 2
fi
# Activate venv if present
if [[ -f "$PROJECT_DIR/.venv/bin/activate" ]]; then
  # shellcheck disable=SC1091
  source "$PROJECT_DIR/.venv/bin/activate"
fi
python -m src.curlai.main "$@"
BINRUN
chmod +x "$BIN_RUN"

# helper test runner
cat > "$PROJECT_DIR/test.sh" <<'TSTR'
#!/usr/bin/env bash
# test.sh - run pytest inside venv
set -euo pipefail
source "$(dirname "$0")/.venv/bin/activate" || true
pytest -q "$@"
TSTR
chmod +x "$PROJECT_DIR/test.sh"

# -----------------------------
# Create a simple Dockerfile (optional) and .env.example
# -----------------------------
cat > "$PROJECT_DIR/Dockerfile" <<'DOCKER'
# Minimal image for running curlai
FROM python:3.11-slim
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "-m", "src.curlai.main"]
DOCKER

cat > "$PROJECT_DIR/.env.example" <<'DOTENV'
# Example environment variables
CURLAI_DEBUG=1
DOTENV

# -----------------------------
# Create a simple CHANGELOG and meta file
# -----------------------------
cat > "$PROJECT_DIR/CHANGELOG.md" <<'CHANGE'
# Changelog

## v1.0 - Initial
- Project scaffolding
CHANGE

cat > "$PROJECT_DIR/META" <<META
name: Curl Ai
author: $GIT_NAME
version: $VERSION
profile: $PROFILE_URL
META

# -----------------------------
# Initialize git repo if not already
# -----------------------------
if [[ ! -d "$PROJECT_DIR/.git" ]]; then
  info "Initializing git repo in $PROJECT_DIR"
  git init "$PROJECT_DIR"
  git -C "$PROJECT_DIR" config user.name "$GIT_NAME"
  git -C "$PROJECT_DIR" config user.email "$GIT_EMAIL"
  # Add files and commit
  git -C "$PROJECT_DIR" add .
  git -C "$PROJECT_DIR" commit -m "chore: initial scaffold for $PROJECT_NAME ($VERSION)"
else
  info "Git repo already exists at $PROJECT_DIR — skipping git init"
fi

# -----------------------------
# Create virtualenv and install requirements
# -----------------------------
if [[ ! -d "$VENV_DIR" ]]; then
  info "Creating virtualenv at $VENV_DIR"
  $PYTHON_BIN -m venv "$VENV_DIR"
fi
# Activate and install
# shellcheck disable=SC1091
source "$VENV_DIR/bin/activate"
info "Upgrading pip and installing requirements"
python -m pip install --upgrade pip >/dev/null
pip install -r "$PROJECT_DIR/requirements.txt"

# -----------------------------
# Success summary and next steps
# -----------------------------
info "Setup completed. Project created at: $PROJECT_DIR"
info "Helper run script at: $BIN_RUN"
info "To start using the project now:"
cat <<EOF
  cd $PROJECT_DIR
  source $VENV_DIR/bin/activate
  $BIN_RUN --version
  # run tests:
  ./test.sh
EOF

exit 0
