package com.eactive.eai.kjb.errors;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.List;

class OAuth2BearerAuthTest {

	private final ObjectMapper objectMapper = new ObjectMapper();

	@Test
	void testCase001_Bearer인증_성공() throws Exception {
		// Step 1: 토큰 발급
		String tokenUrl = TestConfig.getBaseUrl("/oauth2/token");
		String accessToken;

		try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
			HttpPost tokenPost = new HttpPost(tokenUrl);

			List<NameValuePair> params = new ArrayList<>();
			params.add(new BasicNameValuePair("grant_type", "client_credentials"));
			params.add(new BasicNameValuePair("client_id", "AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8"));
			params.add(new BasicNameValuePair("client_secret", "KwBYJT1m1v3SUvzN2HPHhy2Ad9Q2GADbgWkYZZg9Ybbc8R1uEuBJNQ9oVl13b1qiXwYvDWTaX0EanxY4SMjNfnBBsZzfNoMwwDPTb3IjQy5k3CRxTAYzcSnmzlC4FSsG"));
			params.add(new BasicNameValuePair("scope", "api"));

			tokenPost.setEntity(new UrlEncodedFormEntity(params));

			String tokenResponse = httpClient.execute(tokenPost, response -> {
				assertEquals(200, response.getCode(), "토큰 발급 실패");
				return EntityUtils.toString(response.getEntity());
			});

			JsonNode tokenJson = objectMapper.readTree(tokenResponse);
			accessToken = tokenJson.get("access_token").asText();
			assertNotNull(accessToken, "access_token이 null입니다");

			System.out.println("Access Token: " + accessToken);
		}

		// Step 2: Bearer 토큰으로 인증 API 호출
		String apiUrl = TestConfig.getBaseUrl("/api/auth/case009?transactionId=1234567890&parameterTest1=parameterTestValue1&parameterTest2=parameterTestValue2");

		try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
			HttpPost httpPost = new HttpPost(apiUrl);
			httpPost.setHeader("Authorization", "Bearer " + accessToken);
			httpPost.setHeader("Content-Type", "application/json");

			httpPost.setEntity(new StringEntity("{}", ContentType.APPLICATION_JSON));
			
			
			String responseBody = httpClient.execute(httpPost, response -> {
				String body = EntityUtils.toString(response.getEntity());
				System.out.println("Response Body: " + body);

				// then
				assertEquals(200, response.getCode(), "Bearer 인증 실패");
				return body;
			});

			// 응답 검증
			JsonNode jsonNode = objectMapper.readTree(responseBody);
			assertNotNull(jsonNode, "JSON 응답이 null입니다");

			String prettyJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
			System.out.println("API Response:");
			System.out.println(prettyJson);
		}
	}
}
