#include "../src/utils/Logger.h"
#include "../src/core/UsdSceneRenderer.h"
#include "../src/core/ViewportCamera.h"
#include "../src/utils/GLExt.h"
#include <pxr/usd/usd/stage.h>
#include <pxr/usd/usd/primRange.h>
#include <pxr/usd/usdGeom/cube.h>
#include <pxr/usd/usdGeom/sphere.h>
#include <pxr/usd/usdGeom/xform.h>
#include <pxr/usd/usdGeom/bboxCache.h>
#include <pxr/usd/usdGeom/tokens.h>
#include <Windows.h>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>

using namespace UsdLayerManager;
using namespace pxr;

static HWND g_hwnd = nullptr;
static HDC g_hdc = nullptr;
static HGLRC g_hglrc = nullptr;

static int g_testsPassed = 0;
static int g_testsFailed = 0;
static int g_testsSkipped = 0;

#define TEST_ASSERT(cond, msg) \
    do { \
        if (!(cond)) { \
            std::cout << "[FAIL] " << (msg) << " (at " << __FILE__ << ":" << __LINE__ << ")" << std::endl; \
            g_testsFailed++; \
            return false; \
        } else { \
            std::cout << "[PASS] " << (msg) << std::endl; \
            g_testsPassed++; \
        } \
    } while(0)

#define TEST_SKIP(msg) \
    do { \
        std::cout << "[SKIP] " << (msg) << std::endl; \
        g_testsSkipped++; \
        return true; \
    } while(0)

static bool CreateGLContext() {
    WNDCLASSEXW wc = { sizeof(wc), CS_OWNDC, DefWindowProcW, 0L, 0L,
                        GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr,
                        L"ViewportTest", nullptr };
    RegisterClassExW(&wc);

    g_hwnd = CreateWindowW(wc.lpszClassName, L"ViewportTest", WS_OVERLAPPEDWINDOW,
                           100, 100, 800, 600, nullptr, nullptr, wc.hInstance, nullptr);
    if (!g_hwnd) {
        std::cerr << "[FAIL] CreateWindowW failed" << std::endl;
        return false;
    }

    g_hdc = GetDC(g_hwnd);
    PIXELFORMATDESCRIPTOR pfd = {};
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 32;
    pfd.cDepthBits = 24;
    pfd.cStencilBits = 8;

    int pixelFormat = ChoosePixelFormat(g_hdc, &pfd);
    if (pixelFormat == 0) {
        std::cerr << "[FAIL] ChoosePixelFormat failed" << std::endl;
        return false;
    }

    if (!SetPixelFormat(g_hdc, pixelFormat, &pfd)) {
        std::cerr << "[FAIL] SetPixelFormat failed" << std::endl;
        return false;
    }

    g_hglrc = wglCreateContext(g_hdc);
    if (!g_hglrc) {
        std::cerr << "[FAIL] wglCreateContext failed" << std::endl;
        return false;
    }

    if (!wglMakeCurrent(g_hdc, g_hglrc)) {
        std::cerr << "[FAIL] wglMakeCurrent failed" << std::endl;
        return false;
    }

    return true;
}

static void DestroyGLContext() {
    if (g_hglrc) { wglMakeCurrent(nullptr, nullptr); wglDeleteContext(g_hglrc); g_hglrc = nullptr; }
    if (g_hdc) { ReleaseDC(g_hwnd, g_hdc); g_hdc = nullptr; }
    if (g_hwnd) { DestroyWindow(g_hwnd); UnregisterClassW(L"ViewportTest", GetModuleHandle(nullptr)); g_hwnd = nullptr; }
}

static UsdStageRefPtr CreateTestStageWithCube() {
    UsdStageRefPtr stage = UsdStage::CreateInMemory();
    if (!stage) return nullptr;

    UsdGeomXform xform = UsdGeomXform::Define(stage, SdfPath("/TestXform"));
    UsdGeomCube cube = UsdGeomCube::Define(stage, SdfPath("/TestXform/TestCube"));
    cube.GetSizeAttr().Set(50.0);
    cube.GetDisplayColorAttr().Set(VtVec3fArray{{1.0f, 0.0f, 0.0f}});
    cube.GetDisplayOpacityAttr().Set(VtFloatArray{1.0f});

    UsdGeomSphere sphere = UsdGeomSphere::Define(stage, SdfPath("/TestSphere"));
    sphere.GetRadiusAttr().Set(25.0);
    sphere.GetDisplayColorAttr().Set(VtVec3fArray{{0.0f, 1.0f, 0.0f}});
    sphere.GetDisplayOpacityAttr().Set(VtFloatArray{1.0f});

    return stage;
}

static GfVec4d MulMatrixVec4(const GfMatrix4d& m, const GfVec4d& v) {
    GfVec4d result;
    for (int j = 0; j < 4; ++j) {
        result[j] = 0;
        for (int i = 0; i < 4; ++i) {
            result[j] += v[i] * m[i][j];
        }
    }
    return result;
}

bool Test_StageCreation() {
    std::cout << "\n=== Test 1: Stage Creation ===" << std::endl;

    UsdStageRefPtr stage = CreateTestStageWithCube();
    TEST_ASSERT(stage != nullptr, "In-memory stage created");

    size_t primCount = 0;
    for ([[maybe_unused]] const auto& prim : stage->Traverse()) { ++primCount; }
    std::cout << "  Prim count: " << primCount << std::endl;
    TEST_ASSERT(primCount >= 3, "Stage has at least 3 prims (xform, cube, sphere)");

    UsdPrim cubePrim = stage->GetPrimAtPath(SdfPath("/TestXform/TestCube"));
    TEST_ASSERT(cubePrim.IsValid(), "Cube prim found at /TestXform/TestCube");
    TEST_ASSERT(cubePrim.IsA<UsdGeomCube>(), "Prim is a UsdGeomCube");

    UsdPrim spherePrim = stage->GetPrimAtPath(SdfPath("/TestSphere"));
    TEST_ASSERT(spherePrim.IsValid(), "Sphere prim found at /TestSphere");

    return true;
}

bool Test_StageBounds() {
    std::cout << "\n=== Test 2: Stage Bounds Computation ===" << std::endl;

    UsdStageRefPtr stage = CreateTestStageWithCube();
    TEST_ASSERT(stage != nullptr, "Stage created for bounds test");

    UsdSceneRenderer renderer;
    renderer.SetStage(stage);

    GfRange3d bounds = renderer.ComputeStageBounds();
    TEST_ASSERT(!bounds.IsEmpty(), "Stage bounds are not empty");

    GfVec3d min = bounds.GetMin();
    GfVec3d max = bounds.GetMax();
    std::cout << "  Bounds min: (" << min[0] << ", " << min[1] << ", " << min[2] << ")" << std::endl;
    std::cout << "  Bounds max: (" << max[0] << ", " << max[1] << ", " << max[2] << ")" << std::endl;

    GfVec3d size = bounds.GetSize();
    double maxSize = size.GetLength();
    std::cout << "  Bounds size length: " << maxSize << std::endl;
    TEST_ASSERT(maxSize > 0.0, "Bounds size is greater than zero");

    return true;
}

bool Test_CameraSetup() {
    std::cout << "\n=== Test 3: Camera Setup ===" << std::endl;

    ViewportCamera camera;
    TEST_ASSERT(camera.GetMode() == ViewportCamera::CameraMode::Free, "Camera starts in Free mode");

    GfVec3d eye = camera.GetEye();
    GfVec3d focal = camera.GetFocalPoint();
    std::cout << "  Default eye: (" << eye[0] << ", " << eye[1] << ", " << eye[2] << ")" << std::endl;
    std::cout << "  Default focal: (" << focal[0] << ", " << focal[1] << ", " << focal[2] << ")" << std::endl;
    std::cout << "  Near/Far: " << camera.GetNearClip() << " / " << camera.GetFarClip() << std::endl;
    std::cout << "  FOV: " << camera.GetFOV() << ", Aspect: " << camera.GetAspectRatio() << std::endl;

    UsdStageRefPtr stage = CreateTestStageWithCube();
    camera.SetStage(stage);

    GfRange3d bounds = GfRange3d(GfVec3d(-25, -25, -25), GfVec3d(25, 25, 25));
    camera.FrameBoundingBox(bounds);

    eye = camera.GetEye();
    focal = camera.GetFocalPoint();
    std::cout << "  After FrameBB eye: (" << eye[0] << ", " << eye[1] << ", " << eye[2] << ")" << std::endl;
    std::cout << "  After FrameBB focal: (" << focal[0] << ", " << focal[1] << ", " << focal[2] << ")" << std::endl;
    std::cout << "  After FrameBB Near/Far: " << camera.GetNearClip() << " / " << camera.GetFarClip() << std::endl;

    TEST_ASSERT(camera.GetNearClip() > 0.0f, "Near clip is positive after framing");
    TEST_ASSERT(camera.GetFarClip() > camera.GetNearClip(), "Far clip > near clip after framing");

    GfMatrix4d viewMatrix = camera.GetViewMatrix();
    GfMatrix4d projMatrix = camera.GetProjectionMatrix();

    double detView = viewMatrix.GetDeterminant();
    double detProj = projMatrix.GetDeterminant();
    std::cout << "  View matrix determinant: " << detView << std::endl;
    std::cout << "  Proj matrix determinant: " << detProj << std::endl;

    TEST_ASSERT(std::abs(detView) > 0.001, "View matrix is non-degenerate");
    TEST_ASSERT(std::abs(detProj) > 0.000001, "Projection matrix is non-degenerate");

    return true;
}

bool Test_CameraAspectRatio() {
    std::cout << "\n=== Test 4: Camera Aspect Ratio Update ===" << std::endl;

    ViewportCamera camera;
    float defaultAspect = camera.GetAspectRatio();
    std::cout << "  Default aspect: " << defaultAspect << std::endl;

    camera.SetAspectRatio(800.0f / 600.0f);
    float newAspect = camera.GetAspectRatio();
    std::cout << "  After update: " << newAspect << std::endl;
    TEST_ASSERT(std::abs(newAspect - (800.0f / 600.0f)) < 0.01f, "Aspect ratio updated correctly");

    GfMatrix4d proj = camera.GetProjectionMatrix();
    double det = proj.GetDeterminant();
    std::cout << "  Projection determinant with new aspect: " << det << std::endl;
    TEST_ASSERT(std::abs(det) > 0.000001, "Projection matrix valid after aspect update");

    return true;
}

bool Test_ViewProjectionSanity() {
    std::cout << "\n=== Test 5: View/Projection Matrix Sanity ===" << std::endl;

    ViewportCamera camera;
    camera.SetAspectRatio(800.0f / 600.0f);

    GfRange3d bounds(GfVec3d(-25, -25, -25), GfVec3d(25, 25, 25));
    camera.FrameBoundingBox(bounds);

    GfMatrix4d view = camera.GetViewMatrix();
    GfMatrix4d proj = camera.GetProjectionMatrix();

    std::cout << "  View matrix:" << std::endl;
    for (int r = 0; r < 4; ++r) {
        std::cout << "    [" << view[r][0] << ", " << view[r][1] << ", "
                  << view[r][2] << ", " << view[r][3] << "]" << std::endl;
    }

    std::cout << "  Projection matrix:" << std::endl;
    for (int r = 0; r < 4; ++r) {
        std::cout << "    [" << proj[r][0] << ", " << proj[r][1] << ", "
                  << proj[r][2] << ", " << proj[r][3] << "]" << std::endl;
    }

    GfVec3d testPoint(0, 0, 0);
    GfVec4d viewSpacePoint = MulMatrixVec4(view, GfVec4d(testPoint[0], testPoint[1], testPoint[2], 1.0));
    std::cout << "  Origin in view space: (" << viewSpacePoint[0] << ", "
              << viewSpacePoint[1] << ", " << viewSpacePoint[2] << ", "
              << viewSpacePoint[3] << ")" << std::endl;

    TEST_ASSERT(viewSpacePoint[3] != 0.0, "Origin has valid w component in view space");

    GfVec4d clipSpacePoint = MulMatrixVec4(proj, viewSpacePoint);
    std::cout << "  Origin in clip space: (" << clipSpacePoint[0] << ", "
              << clipSpacePoint[1] << ", " << clipSpacePoint[2] << ", "
              << clipSpacePoint[3] << ")" << std::endl;

    if (clipSpacePoint[3] != 0.0) {
        double ndcX = clipSpacePoint[0] / clipSpacePoint[3];
        double ndcY = clipSpacePoint[1] / clipSpacePoint[3];
        double ndcZ = clipSpacePoint[2] / clipSpacePoint[3];
        std::cout << "  Origin in NDC: (" << ndcX << ", " << ndcY << ", " << ndcZ << ")" << std::endl;

        bool inFrustum = (ndcX >= -1.0 && ndcX <= 1.0 &&
                          ndcY >= -1.0 && ndcY <= 1.0 &&
                          ndcZ >= -1.0 && ndcZ <= 1.0);
        if (inFrustum) {
            std::cout << "  [PASS] Scene origin is inside the view frustum" << std::endl;
            g_testsPassed++;
        } else {
            std::cout << "  [FAIL] Scene origin is OUTSIDE the view frustum - this explains nothing visible!" << std::endl;
            std::cout << "  This likely means the camera framing calculation is wrong." << std::endl;
            g_testsFailed++;
        }
    } else {
        std::cout << "  [FAIL] Clip space w=0 - projection is broken" << std::endl;
        g_testsFailed++;
    }

    return true;
}

bool Test_RendererInitAndRender() {
    std::cout << "\n=== Test 6: Renderer Init and Render ===" << std::endl;

    if (!GL::InitExtensions()) {
        TEST_SKIP("OpenGL extensions not available");
    }

    UsdStageRefPtr stage = CreateTestStageWithCube();
    TEST_ASSERT(stage != nullptr, "Test stage created");

    UsdSceneRenderer renderer;
    renderer.SetStage(stage);

    GfRange3d bounds = renderer.ComputeStageBounds();
    TEST_ASSERT(!bounds.IsEmpty(), "Stage bounds not empty");

    ViewportCamera camera;
    camera.SetStage(stage);
    camera.FrameBoundingBox(bounds);
    camera.SetAspectRatio(800.0f / 600.0f);

    renderer.SetCameraState(camera.GetViewMatrix(), camera.GetProjectionMatrix());

    int width = 800, height = 600;
    renderer.Render(width, height);

    uint32_t texID = renderer.GetColorTextureID();
    std::cout << "  Color texture ID: " << texID << std::endl;
    TEST_ASSERT(texID != 0, "Renderer produced a valid texture ID");

    GfVec3f bgColor = renderer.GetBackgroundColor();
    std::cout << "  Background color: (" << bgColor[0] << ", " << bgColor[1] << ", " << bgColor[2] << ")" << std::endl;

    return true;
}

bool Test_RendererDrawTargetValid() {
    std::cout << "\n=== Test 7: Renderer DrawTarget Validity ===" << std::endl;

    if (!GL::InitExtensions()) {
        TEST_SKIP("OpenGL extensions not available");
    }

    UsdStageRefPtr stage = CreateTestStageWithCube();
    TEST_ASSERT(stage != nullptr, "Test stage created");

    UsdSceneRenderer renderer;
    renderer.SetStage(stage);

    ViewportCamera camera;
    camera.SetStage(stage);
    GfRange3d bounds = renderer.ComputeStageBounds();
    if (!bounds.IsEmpty()) {
        camera.FrameBoundingBox(bounds);
    }
    camera.SetAspectRatio(400.0f / 300.0f);
    renderer.SetCameraState(camera.GetViewMatrix(), camera.GetProjectionMatrix());

    renderer.Render(400, 300);

    auto drawTarget = renderer.GetDrawTargetForTest();
    TEST_ASSERT(drawTarget != nullptr, "DrawTarget is not null after render");

    if (drawTarget) {
        GLuint fboId = drawTarget->GetFramebufferId();
        auto colorAttach = drawTarget->GetAttachment("color");
        auto depthAttach = drawTarget->GetAttachment("depth");

        std::cout << "  FBO ID: " << fboId << std::endl;
        std::cout << "  Color attachment: " << (colorAttach ? "present" : "MISSING") << std::endl;
        std::cout << "  Depth attachment: " << (depthAttach ? "present" : "MISSING") << std::endl;

        TEST_ASSERT(fboId != 0, "FBO ID is non-zero");
        TEST_ASSERT(colorAttach != nullptr, "Color attachment exists");
        TEST_ASSERT(depthAttach != nullptr, "Depth attachment exists");

        if (colorAttach) {
            GLuint texId = colorAttach->GetGlTextureName();
            std::cout << "  Color texture ID: " << texId << std::endl;
            TEST_ASSERT(texId != 0, "Color attachment has valid GL texture");

            GfVec2i texSize = drawTarget->GetSize();
            std::cout << "  DrawTarget size: " << texSize[0] << "x" << texSize[1] << std::endl;
            TEST_ASSERT(texSize[0] > 0 && texSize[1] > 0, "DrawTarget has non-zero size");
        }
    }

    return true;
}

bool Test_MultipleRenderFrames() {
    std::cout << "\n=== Test 8: Multiple Render Frames (Stability) ===" << std::endl;

    if (!GL::InitExtensions()) {
        TEST_SKIP("OpenGL extensions not available");
    }

    UsdStageRefPtr stage = CreateTestStageWithCube();
    TEST_ASSERT(stage != nullptr, "Stage created for stability test");

    UsdSceneRenderer renderer;
    renderer.SetStage(stage);

    ViewportCamera camera;
    camera.SetStage(stage);
    GfRange3d bounds = renderer.ComputeStageBounds();
    if (!bounds.IsEmpty()) {
        camera.FrameBoundingBox(bounds);
    }
    camera.SetAspectRatio(400.0f / 300.0f);
    renderer.SetCameraState(camera.GetViewMatrix(), camera.GetProjectionMatrix());

    for (int i = 0; i < 5; ++i) {
        renderer.Render(400, 300);
        uint32_t texID = renderer.GetColorTextureID();
        if (texID == 0) {
            std::cout << "[FAIL] Render frame " << i << " produced invalid texture" << std::endl;
            g_testsFailed++;
            return false;
        }
    }

    std::cout << "  [PASS] 5 consecutive renders completed successfully" << std::endl;
    g_testsPassed++;
    return true;
}

bool Test_CameraOrbitAndRender() {
    std::cout << "\n=== Test 9: Camera Orbit + Render ===" << std::endl;

    if (!GL::InitExtensions()) {
        TEST_SKIP("OpenGL extensions not available");
    }

    UsdStageRefPtr stage = CreateTestStageWithCube();
    TEST_ASSERT(stage != nullptr, "Stage created for orbit test");

    UsdSceneRenderer renderer;
    renderer.SetStage(stage);

    ViewportCamera camera;
    camera.SetStage(stage);
    GfRange3d bounds = renderer.ComputeStageBounds();
    if (!bounds.IsEmpty()) {
        camera.FrameBoundingBox(bounds);
    }
    camera.SetAspectRatio(400.0f / 300.0f);

    for (int angle = 0; angle < 4; ++angle) {
        camera.Orbit(45.0f, 0.0f);
        renderer.SetCameraState(camera.GetViewMatrix(), camera.GetProjectionMatrix());
        renderer.Render(400, 300);

        uint32_t texID = renderer.GetColorTextureID();
        if (texID == 0) {
            std::cout << "[FAIL] Render after orbit " << angle << " failed" << std::endl;
            g_testsFailed++;
            return false;
        }
    }

    std::cout << "  [PASS] Renders after camera orbit completed" << std::endl;
    g_testsPassed++;
    return true;
}

bool Test_EmptyStageRender() {
    std::cout << "\n=== Test 10: Empty Stage Render ===" << std::endl;

    if (!GL::InitExtensions()) {
        TEST_SKIP("OpenGL extensions not available");
    }

    UsdStageRefPtr stage = UsdStage::CreateInMemory();
    TEST_ASSERT(stage != nullptr, "Empty in-memory stage created");

    UsdSceneRenderer renderer;
    renderer.SetBackgroundColor(GfVec3f(0.1f, 0.1f, 0.15f));
    renderer.SetStage(stage);

    ViewportCamera camera;
    camera.SetStage(stage);
    camera.SetAspectRatio(400.0f / 300.0f);
    renderer.SetCameraState(camera.GetViewMatrix(), camera.GetProjectionMatrix());

    renderer.Render(400, 300);

    uint32_t texID = renderer.GetColorTextureID();
    TEST_ASSERT(texID != 0, "Empty stage still produces a valid texture");

    auto drawTarget = renderer.GetDrawTargetForTest();
    if (drawTarget) {
        std::cout << "  Empty stage FBO: " << drawTarget->GetFramebufferId() << std::endl;
        std::cout << "  [PASS] Empty stage render produces valid FBO" << std::endl;
        g_testsPassed++;
    }

    return true;
}

bool Test_CameraFrameSceneIntegration() {
    std::cout << "\n=== Test 11: Camera + FrameScene Integration ===" << std::endl;

    UsdStageRefPtr stage = CreateTestStageWithCube();
    TEST_ASSERT(stage != nullptr, "Stage created for integration test");

    ViewportCamera camera;
    camera.SetStage(stage);

    UsdSceneRenderer renderer;
    renderer.SetStage(stage);

    GfRange3d bounds = renderer.ComputeStageBounds();
    TEST_ASSERT(!bounds.IsEmpty(), "Stage has bounds for framing");

    camera.FrameBoundingBox(bounds);

    float nearClip = camera.GetNearClip();
    float farClip = camera.GetFarClip();
    float distance = 0.0f;

    GfVec3d eye = camera.GetEye();
    GfVec3d focal = camera.GetFocalPoint();
    GfVec3d diff = eye - focal;
    distance = static_cast<float>(diff.GetLength());

    std::cout << "  Camera distance after FrameBoundingBox: " << distance << std::endl;
    std::cout << "  Near clip: " << nearClip << ", Far clip: " << farClip << std::endl;
    std::cout << "  Eye: (" << eye[0] << ", " << eye[1] << ", " << eye[2] << ")" << std::endl;

    TEST_ASSERT(distance > 0.0f, "Camera has non-zero distance from focal point");
    TEST_ASSERT(nearClip > 0.0f, "Near clip is positive");
    TEST_ASSERT(farClip > nearClip, "Far clip is beyond near clip");
    TEST_ASSERT(nearClip < distance, "Near clip is less than camera distance (scene is in front of camera)");

    GfMatrix4d view = camera.GetViewMatrix();
    GfMatrix4d proj = camera.GetProjectionMatrix();

    GfVec4d originView = MulMatrixVec4(view, GfVec4d(0, 0, 0, 1));
    if (originView[3] != 0.0) {
        GfVec4d originClip = MulMatrixVec4(proj, originView);
        if (originClip[3] != 0.0) {
            double ndcZ = originClip[2] / originClip[3];
            std::cout << "  Scene origin NDC Z: " << ndcZ << std::endl;
            bool zInRange = (ndcZ >= -1.0 && ndcZ <= 1.0);
            TEST_ASSERT(zInRange, "Scene origin is within NDC Z range [-1,1] - visible in depth");
        }
    }

    return true;
}

int main() {
    std::cout << "============================================" << std::endl;
    std::cout << "  Viewport Display Logic Test Suite" << std::endl;
    std::cout << "============================================" << std::endl;

    char exePath[MAX_PATH];
    GetModuleFileNameA(nullptr, exePath, MAX_PATH);
    std::string exeDir(exePath);
    size_t lastSlash = exeDir.find_last_of("\\/");
    if (lastSlash != std::string::npos) {
        exeDir = exeDir.substr(0, lastSlash);
    }
    std::string pluginPath = exeDir + "\\usd";
    SetEnvironmentVariableA("PXR_PLUGINPATH_NAME", pluginPath.c_str());

    Logger::Instance().SetLogLevel(LogLevel::Warning);

    if (!CreateGLContext()) {
        std::cerr << "FATAL: Cannot create OpenGL context. Tests require a valid GL context." << std::endl;
        return 1;
    }

    GL::InitExtensions();

    Test_StageCreation();
    Test_StageBounds();
    Test_CameraSetup();
    Test_CameraAspectRatio();
    Test_ViewProjectionSanity();
    Test_CameraFrameSceneIntegration();
    Test_RendererInitAndRender();
    Test_RendererDrawTargetValid();
    Test_MultipleRenderFrames();
    Test_CameraOrbitAndRender();
    Test_EmptyStageRender();

    std::cout << "\n============================================" << std::endl;
    std::cout << "  Results: " << g_testsPassed << " passed, "
              << g_testsFailed << " failed, "
              << g_testsSkipped << " skipped" << std::endl;
    std::cout << "============================================" << std::endl;

    if (g_testsFailed > 0) {
        std::cout << "\n  DIAGNOSIS: If Test 5 (View/Projection Sanity) shows the origin" << std::endl;
        std::cout << "  is outside the frustum, the camera framing logic in" << std::endl;
        std::cout << "  ViewportCamera::FrameBoundingBox() is broken. Check:" << std::endl;
        std::cout << "  1. The view matrix construction in ComputeFreeViewMatrix()" << std::endl;
        std::cout << "  2. The projection matrix in ComputeFreeProjectionMatrix()" << std::endl;
        std::cout << "  3. Whether GfMatrix4d row/column conventions match USD's expectations" << std::endl;
    }

    DestroyGLContext();

    return g_testsFailed > 0 ? 1 : 0;
}
