#!/bin/bash
#
# Unit tests for branch.sh script
# Run from project root: ./tools/test_branch.sh
#

# Don't exit on error - we want to run all tests
set +e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Test counters
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0

# Save current branch
ORIGINAL_BRANCH=$(git branch --show-current)

# Cleanup function
cleanup() {
    # Remove test user cache files
    rm -f ~/.qtx_branch_last_user 2>/dev/null || true

    # Return to original branch
    git checkout "$ORIGINAL_BRANCH" 2>/dev/null || git checkout develop 2>/dev/null || true

    # Delete test branches
    git branch 2>/dev/null | grep -E "(testuser|cached_user|user123|typetest|nametest|secureuser|validationtest)" | xargs -r git branch -D 2>/dev/null || true
}

# Setup
trap cleanup EXIT

echo "========================================"
echo "  Branch Script Unit Tests"
echo "========================================"
echo ""

# Test helper function - pass test
pass_test() {
    local test_name="$1"
    TESTS_RUN=$((TESTS_RUN + 1))
    TESTS_PASSED=$((TESTS_PASSED + 1))
    echo -e "${GREEN}✓${NC} PASS: $test_name"
}

# Test helper function - fail test
fail_test() {
    local test_name="$1"
    local reason="$2"
    TESTS_RUN=$((TESTS_RUN + 1))
    TESTS_FAILED=$((TESTS_FAILED + 1))
    echo -e "${RED}✗${NC} FAIL: $test_name${reason:+ - $reason}"
}

echo "Running tests..."
echo ""

# ====================
# Test 1: Valid branch creation
# ====================
echo "Test Suite 1: Valid Branch Creation"
echo "------------------------------------"

cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
1
testuser
123
valid branch
EOF

if git rev-parse --verify "feature/testuser/SKL-123/valid_branch" &>/dev/null; then
    pass_test "Create valid feature branch"
else
    fail_test "Create valid feature branch" "Branch not found"
fi

if [[ "$(git branch --show-current)" == "feature/testuser/SKL-123/valid_branch" ]]; then
    pass_test "Checkout to created branch"
else
    fail_test "Checkout to created branch" "Not on expected branch"
fi

git checkout develop &>/dev/null
echo ""

# ====================
# Test 2: User cache functionality
# ====================
echo "Test Suite 2: User Cache Functionality"
echo "---------------------------------------"

# Create cache file
rm -f ~/.qtx_branch_last_user
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
6
cached_user
456
using cache
EOF

if [[ -f ~/.qtx_branch_last_user ]]; then
    pass_test "User cache file created"
else
    fail_test "User cache file created" "File not found"
fi

# Check permissions
PERMS=$(stat -f "%Lp" ~/.qtx_branch_last_user 2>/dev/null || stat -c "%a" ~/.qtx_branch_last_user 2>/dev/null)
if [[ "$PERMS" == "600" ]]; then
    pass_test "User cache has secure permissions (600)"
else
    fail_test "User cache has secure permissions (600)" "Got $PERMS"
fi

if grep -q "cached_user" ~/.qtx_branch_last_user; then
    pass_test "User cache contains correct value"
else
    fail_test "User cache contains correct value"
fi

git checkout develop &>/dev/null
echo ""

# ====================
# Test 3: Input validation
# ====================
echo "Test Suite 3: Input Validation"
echo "-------------------------------"

# Test invalid username with special characters
OUTPUT=$(cat << 'EOF' 2>/dev/null | timeout 5 ./tools/branch.sh 2>&1 || true
1
user@invalid
EOF
)

if echo "$OUTPUT" | grep -q "Error: user must be alphanumeric"; then
    pass_test "Reject username with special characters"
else
    fail_test "Reject username with special characters"
fi

# Test non-numeric issue number
OUTPUT=$(cat << 'EOF' 2>/dev/null | timeout 5 ./tools/branch.sh 2>&1 || true
1
validationtest
abc123
EOF
)

if echo "$OUTPUT" | grep -q "Error: issue number must be numeric"; then
    pass_test "Reject non-numeric issue number"
else
    fail_test "Reject non-numeric issue number"
fi

# Test empty summary
OUTPUT=$(cat << 'EOF' 2>/dev/null | timeout 5 ./tools/branch.sh 2>&1 || true
1
validationtest
999

EOF
)

if echo "$OUTPUT" | grep -q "Error: summary is required"; then
    pass_test "Reject empty summary"
else
    fail_test "Reject empty summary"
fi

# Test summary too long (over 100 chars)
LONG_SUMMARY="this is a very long summary that exceeds one hundred characters and should be rejected by the validation"
OUTPUT=$(cat << EOF 2>/dev/null | timeout 5 ./tools/branch.sh 2>&1 || true
1
validationtest
999
$LONG_SUMMARY
EOF
)

if echo "$OUTPUT" | grep -q "Error: summary too long"; then
    pass_test "Reject summary over 100 characters"
else
    fail_test "Reject summary over 100 characters"
fi

echo ""

# ====================
# Test 4: ISSUE_PREFIX extraction
# ====================
echo "Test Suite 4: ISSUE_PREFIX Extraction"
echo "--------------------------------------"

# Backup original Makefile.common
cp Makefile.common Makefile.common.backup

# Test with different prefix
cat > Makefile.common << 'EOF'
ISSUE_PREFIX := TEST
GOPATH ?= $(shell go env GOPATH)
EOF

cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
1
user123
789
different prefix
EOF

# Restore original
mv Makefile.common.backup Makefile.common

if git rev-parse --verify "feature/user123/TEST-789/different_prefix" &>/dev/null; then
    pass_test "Create branch with custom ISSUE_PREFIX"
else
    fail_test "Create branch with custom ISSUE_PREFIX" "Branch not found with TEST prefix"
fi

git checkout develop &>/dev/null
echo ""

# ====================
# Test 5: Branch name formatting
# ====================
echo "Test Suite 5: Branch Name Formatting"
echo "-------------------------------------"

# Spaces should become underscores
BRANCH_OUTPUT=$(cat << 'EOF' | timeout 10 ./tools/branch.sh 2>&1
2
nametest
111
spaces in summary here
EOF
)

if echo "$BRANCH_OUTPUT" | grep -q "hotfix/nametest/SKL-111/spaces_in_summary_here"; then
    pass_test "Spaces converted to underscores in branch name"
else
    fail_test "Spaces converted to underscores in branch name"
fi

git branch -D "hotfix/nametest/SKL-111/spaces_in_summary_here" &>/dev/null || true
git checkout develop &>/dev/null
echo ""

# ====================
# Test 6: Different branch types
# ====================
echo "Test Suite 6: All Branch Types"
echo "-------------------------------"

# Test feature type
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
1
typetest
301
test feature
EOF

if git rev-parse --verify "feature/typetest/SKL-301/test_feature" &>/dev/null; then
    pass_test "Branch type 'feature' works"
    git branch -D "feature/typetest/SKL-301/test_feature" &>/dev/null
else
    fail_test "Branch type 'feature' works"
fi

# Test hotfix type
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
2
typetest
302
test hotfix
EOF

if git rev-parse --verify "hotfix/typetest/SKL-302/test_hotfix" &>/dev/null; then
    pass_test "Branch type 'hotfix' works"
    git branch -D "hotfix/typetest/SKL-302/test_hotfix" &>/dev/null
else
    fail_test "Branch type 'hotfix' works"
fi

# Test fix type
cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
6
typetest
306
test fix
EOF

if git rev-parse --verify "fix/typetest/SKL-306/test_fix" &>/dev/null; then
    pass_test "Branch type 'fix' works"
    git branch -D "fix/typetest/SKL-306/test_fix" &>/dev/null
else
    fail_test "Branch type 'fix' works"
fi

git checkout develop &>/dev/null
echo ""

# ====================
# Test 7: Symlink attack prevention
# ====================
echo "Test Suite 7: Security - Symlink Prevention"
echo "--------------------------------------------"

# Create a symlink as the user file
USER_CACHE=~/.qtx_branch_last_user
TEMP_TARGET=$(mktemp)
rm -f "$USER_CACHE"
ln -s "$TEMP_TARGET" "$USER_CACHE"

cat << 'EOF' | timeout 10 ./tools/branch.sh &>/dev/null
1
secureuser
999
security test
EOF

# Check if symlink was removed and replaced with regular file
if [[ -L "$USER_CACHE" ]]; then
    fail_test "Symlink removed before writing" "Symlink still exists (security risk)"
else
    pass_test "Symlink removed before writing (secure)"
fi

rm -f "$TEMP_TARGET"
git branch -D "feature/secureuser/SKL-999/security_test" &>/dev/null || true
git checkout develop &>/dev/null
echo ""

# ====================
# Summary
# ====================
echo "========================================"
echo "  Test Summary"
echo "========================================"
echo -e "Total:  $TESTS_RUN"
echo -e "${GREEN}Passed: $TESTS_PASSED${NC}"
if [[ $TESTS_FAILED -gt 0 ]]; then
    echo -e "${RED}Failed: $TESTS_FAILED${NC}"
else
    echo -e "Failed: $TESTS_FAILED"
fi
echo ""

if [[ $TESTS_FAILED -eq 0 ]]; then
    echo -e "${GREEN}✓ All tests passed!${NC}"
    exit 0
else
    echo -e "${RED}✗ Some tests failed!${NC}"
    exit 1
fi
