Documentation
// Copyright (c) 2025, Salesforce, Inc.,
// All rights reserved.
// For full license text, see the LICENSE.txt file

use anyhow::Result;

use httpmock::MockServer;
use pdk_test::services::httpmock::{HttpMock, HttpMockConfig};
use pdk_test::{pdk_test, TestComposite, TestError};

#[ignore = "Mutiple instance support is broken."]
#[pdk_test]
async fn httpmock() -> Result<()> {
    let composite = TestComposite::builder()
        .with_service(HttpMockConfig::default())
        .build()
        .await?;

    let httpmock: HttpMock = composite.service()?;

    let mock_server = MockServer::connect_async(httpmock.socket()).await;

    mock_server
        .mock_async(|when, then| {
            when.path("/hello");
            then.body("World!");
        })
        .await;

    let response = reqwest::get(format!("{}/hello", mock_server.base_url())).await?;

    assert_eq!(response.status(), 200);
    assert_eq!(response.text().await?, "World!");

    Ok(())
}

#[pdk_test]
async fn httpmock_with_sync_mock() -> Result<()> {
    let composite = TestComposite::builder()
        .with_service(HttpMockConfig::default())
        .build()
        .await?;

    let httpmock: HttpMock = composite.service()?;

    let mock_server = MockServer::connect_async(httpmock.socket()).await;

    let mock = mock_server.mock(|when, then| {
        when.path("/hello");
        then.body("World!");
    });

    let _response = reqwest::get(format!("{}/hello", mock_server.base_url())).await?;

    mock.assert_hits(1);

    Ok(())
}

#[pdk_test]
async fn test_with_multiple_httpmocks_does_not_work() -> Result<()> {
    let first_httpmock = HttpMockConfig::default();

    let second_httpmock = HttpMockConfig::builder()
        .port(6000)
        .hostname("another")
        .build();

    let result = TestComposite::builder()
        .with_service(first_httpmock)
        .with_service(second_httpmock)
        .build()
        .await;

    assert!(result.is_err());
    assert_eq!(
        result.err().unwrap().to_string(),
        "Configuration not supported: Only 1 HttpMock can be defined per test"
    );

    Ok(())
}

#[pdk_test]
async fn invalid_explicit_image_name() {
    let httpmock_config = HttpMockConfig::builder()
        .image_name("unknown/httpmock")
        .build();

    let result = TestComposite::builder()
        .with_service(httpmock_config)
        .build()
        .await;

    assert!(result.is_err());

    let Err(error) = result else {
        unreachable!();
    };

    assert!(matches!(error, TestError::Docker(_)));
}