#!/bin/bash
# ISO 27001 資產盤點系統 - 完整測試腳本

set -e  # 遇到錯誤立即退出

# 顏色定義
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 測試計數
TOTAL_TESTS=0
PASSED_TESTS=0
FAILED_TESTS=0

# 測試結果記錄
declare -a FAILED_TEST_NAMES

# 顯示標題
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}ISO 27001 系統完整測試${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""

# 測試函數
run_test() {
    local test_name="$1"
    local test_command="$2"
    
    TOTAL_TESTS=$((TOTAL_TESTS + 1))
    echo -n "測試 $TOTAL_TESTS: $test_name ... "
    
    if eval "$test_command" > /dev/null 2>&1; then
        echo -e "${GREEN}✓ 通過${NC}"
        PASSED_TESTS=$((PASSED_TESTS + 1))
        return 0
    else
        echo -e "${RED}✗ 失敗${NC}"
        FAILED_TESTS=$((FAILED_TESTS + 1))
        FAILED_TEST_NAMES+=("$test_name")
        return 1
    fi
}

run_test_with_output() {
    local test_name="$1"
    local test_command="$2"
    local expected_output="$3"
    
    TOTAL_TESTS=$((TOTAL_TESTS + 1))
    echo -n "測試 $TOTAL_TESTS: $test_name ... "
    
    OUTPUT=$(eval "$test_command" 2>&1)
    
    if echo "$OUTPUT" | grep -q "$expected_output"; then
        echo -e "${GREEN}✓ 通過${NC}"
        PASSED_TESTS=$((PASSED_TESTS + 1))
        return 0
    else
        echo -e "${RED}✗ 失敗${NC}"
        echo "  預期包含: $expected_output"
        echo "  實際輸出: $OUTPUT"
        FAILED_TESTS=$((FAILED_TESTS + 1))
        FAILED_TEST_NAMES+=("$test_name")
        return 1
    fi
}

# API URL
API_URL="http://localhost:8000/api"
TOKEN=""

echo -e "${YELLOW}[階段 1] 環境檢查${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

# 1. 檢查 Docker 服務
run_test "Docker Compose 運行中" "docker compose ps | grep -q 'Up'"

# 2. 檢查 Backend 服務
run_test "Backend 容器運行中" "docker compose ps | grep backend | grep -q 'Up'"

# 3. 檢查 Database 服務
run_test "Database 容器運行中" "docker compose ps | grep db | grep -q 'Up'"

# 4. 檢查 Redis 服務
run_test "Redis 容器運行中" "docker compose ps | grep redis | grep -q 'Up'"

# 5. 檢查 Backend HTTP 回應 (測試登入端點，不需認證)
run_test "Backend API 可存取" "curl -s -o /dev/null -w '%{http_code}' $API_URL/auth/login/ | grep -q '405'"  # POST-only endpoint returns 405 for GET

echo ""
echo -e "${YELLOW}[階段 2] 資料庫測試${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

# 6. 檢查資料庫連線
run_test "PostgreSQL 可連線" "docker compose exec -T db pg_isready -U postgres"

# 7. 檢查使用者數量
run_test_with_output "使用者資料存在" \
    "docker compose exec -T backend python manage.py shell -c 'from accounts.models import User; print(User.objects.count())'" \
    "5"

# 8. 檢查資產數量
run_test_with_output "資產資料存在" \
    "docker compose exec -T backend python manage.py shell -c 'from assets.models import Asset; print(Asset.objects.count())'" \
    "19"

# 9. 檢查資產關係
run_test_with_output "資產關係資料存在" \
    "docker compose exec -T backend python manage.py shell -c 'from assets.models import AssetRelationship; print(AssetRelationship.objects.count())'" \
    "8"

echo ""
echo -e "${YELLOW}[階段 3] API 認證測試${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

# 10. 測試登入 API
RESPONSE=$(curl -s -X POST $API_URL/auth/login/ \
    -H "Content-Type: application/json" \
    -d '{"username":"admin","password":"demo1234"}')

if echo "$RESPONSE" | grep -q '"access_token"'; then
    echo -e "測試 10: 登入 API ... ${GREEN}✓ 通過${NC}"
    TOTAL_TESTS=$((TOTAL_TESTS + 1))
    PASSED_TESTS=$((PASSED_TESTS + 1))
    TOKEN=$(echo "$RESPONSE" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
    echo "  已取得 Token: ${TOKEN:0:20}..."
else
    echo -e "測試 10: 登入 API ... ${RED}✗ 失敗${NC}"
    echo "  回應: $RESPONSE"
    TOTAL_TESTS=$((TOTAL_TESTS + 1))
    FAILED_TESTS=$((FAILED_TESTS + 1))
    FAILED_TEST_NAMES+=("登入 API")
fi

echo ""
echo -e "${YELLOW}[階段 4] 資產管理 API 測試${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

if [ -n "$TOKEN" ]; then
    # 11. 測試資產列表 API
    run_test_with_output "取得資產列表" \
        "curl -s -H 'Authorization: Bearer $TOKEN' $API_URL/assets/" \
        '"count"'
    
    # 12. 測試資產統計 API
    run_test_with_output "取得資產統計" \
        "curl -s -H 'Authorization: Bearer $TOKEN' $API_URL/assets/statistics/" \
        '"total"'
    
    # 13. 測試資產搜尋
    run_test_with_output "搜尋資產 (Server)" \
        "curl -s -H 'Authorization: Bearer $TOKEN' '$API_URL/assets/?search=Server'" \
        '"name"'
    
    # 14. 測試資產篩選 (硬體)
    run_test_with_output "篩選硬體資產" \
        "curl -s -H 'Authorization: Bearer $TOKEN' '$API_URL/assets/?asset_type=hardware'" \
        '"asset_type":"hardware"'
    
    # 15. 測試資產篩選 (使用中)
    run_test_with_output "篩選使用中資產" \
        "curl -s -H 'Authorization: Bearer $TOKEN' '$API_URL/assets/?status=active'" \
        '"status":"active"'
    
    # 16. 測試取得單一資產
    FIRST_ASSET_ID=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/assets/" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4)
    if [ -n "$FIRST_ASSET_ID" ]; then
        run_test_with_output "取得資產詳情" \
            "curl -s -H 'Authorization: Bearer $TOKEN' $API_URL/assets/$FIRST_ASSET_ID/" \
            '"asset_number"'
    else
        echo -e "測試 16: 取得資產詳情 ... ${YELLOW}⊘ 跳過 (無資產ID)${NC}"
    fi
    
    # 17. 測試新增資產 (然後刪除)
    NEW_ASSET=$(curl -s -X POST -H "Authorization: Bearer $TOKEN" \
        -H "Content-Type: application/json" \
        -d '{"asset_number":"TEST-001","name":"測試資產","asset_type":"hardware","status":"active","confidentiality":"low","integrity":"low","availability":"low"}' \
        "$API_URL/assets/")
    
    if echo "$NEW_ASSET" | grep -q '"asset_number":"TEST-001"'; then
        echo -e "測試 17: 新增資產 ... ${GREEN}✓ 通過${NC}"
        TOTAL_TESTS=$((TOTAL_TESTS + 1))
        PASSED_TESTS=$((PASSED_TESTS + 1))
        
        # 取得新建資產的 ID 並刪除
        NEW_ASSET_ID=$(echo "$NEW_ASSET" | grep -o '"id":"[^"]*' | cut -d'"' -f4)
        if [ -n "$NEW_ASSET_ID" ]; then
            curl -s -X DELETE -H "Authorization: Bearer $TOKEN" "$API_URL/assets/$NEW_ASSET_ID/" > /dev/null
            echo "  ℹ 已清理測試資產"
        fi
    else
        echo -e "測試 17: 新增資產 ... ${RED}✗ 失敗${NC}"
        TOTAL_TESTS=$((TOTAL_TESTS + 1))
        FAILED_TESTS=$((FAILED_TESTS + 1))
        FAILED_TEST_NAMES+=("新增資產")
    fi
    
else
    echo -e "${YELLOW}⊘ 跳過 API 測試 (無 Token)${NC}"
fi

echo ""
echo -e "${YELLOW}[階段 5] 前端測試${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

# 18. 檢查前端檔案存在
run_test "前端原始碼存在" "test -d frontend/src"

# 19. 檢查 package.json
run_test "package.json 存在" "test -f frontend/package.json"

# 20. 檢查 node_modules (如果已安裝)
if [ -d "frontend/node_modules" ]; then
    run_test "前端依賴已安裝" "test -d frontend/node_modules"
else
    echo -e "測試 20: 前端依賴已安裝 ... ${YELLOW}⊘ 跳過 (未安裝)${NC}"
fi

echo ""
echo -e "${YELLOW}[階段 6] 文件檢查${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

# 21-25. 檢查各種文件
run_test "README.md 存在" "test -f README.md"
run_test "plan.md 存在" "test -f plan.md"
run_test "QUICK_START_GUIDE.md 存在" "test -f QUICK_START_GUIDE.md"
run_test "FINAL_COMPLETION_REPORT.md 存在" "test -f FINAL_COMPLETION_REPORT.md"
run_test "規格文件目錄存在" "test -d spec && ls spec/*.md > /dev/null"

echo ""
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}測試摘要${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
echo "總測試數: $TOTAL_TESTS"
echo -e "${GREEN}通過: $PASSED_TESTS${NC}"
echo -e "${RED}失敗: $FAILED_TESTS${NC}"
echo ""

if [ $FAILED_TESTS -gt 0 ]; then
    echo -e "${RED}失敗的測試:${NC}"
    for test_name in "${FAILED_TEST_NAMES[@]}"; do
        echo "  ✗ $test_name"
    done
    echo ""
fi

# 計算通過率
PASS_RATE=$((PASSED_TESTS * 100 / TOTAL_TESTS))
echo "通過率: ${PASS_RATE}%"

if [ $PASS_RATE -ge 90 ]; then
    echo -e "${GREEN}✓ 系統狀態良好！${NC}"
    exit 0
elif [ $PASS_RATE -ge 70 ]; then
    echo -e "${YELLOW}⚠ 系統部分功能異常${NC}"
    exit 1
else
    echo -e "${RED}✗ 系統狀態不佳${NC}"
    exit 2
fi
