-- Redmine #749
-- Compare Select AI prompt and SQL generation with annotations enabled/disabled.
-- The Korean prompt is reconstructed from UTF-8 Base64 inside Oracle.

SET SERVEROUTPUT ON SIZE UNLIMITED
SET FEEDBACK OFF
SET VERIFY OFF
WHENEVER SQLERROR EXIT SQL.SQLCODE

DECLARE
  c_annotation_profile CONSTANT VARCHAR2(128) := 'HMM_HR_DATA_GPT54_PROFILE';
  c_no_annotation_profile CONSTANT VARCHAR2(128) := 'HMM_HR_DATA_GPT54_NOANN_PROFILE';
  c_prompt_base64 CONSTANT VARCHAR2(4000) :=
    '7J2067KIIOuLrCDtjIDsm5Drs4Qg7Zy06rCAIOyCrOyaqSDtmITtmansnYQg67O07Jes7KSY';

  l_prompt VARCHAR2(4000) :=
    UTL_I18N.RAW_TO_CHAR(
      UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(c_prompt_base64)),
      'AL32UTF8'
    );

  PROCEDURE run_one(
    p_run_no       IN PLS_INTEGER,
    p_action       IN VARCHAR2,
    p_profile_name IN VARCHAR2
  ) IS
    l_started     PLS_INTEGER;
    l_elapsed_ms PLS_INTEGER;
    l_result      CLOB;
    l_result_head VARCHAR2(32767);
    l_result_hash VARCHAR2(128);
    l_valid_sql   VARCHAR2(1) := '-';
  BEGIN
    l_started := DBMS_UTILITY.GET_TIME;
    l_result := DBMS_CLOUD_AI.GENERATE(
      l_prompt,
      p_profile_name,
      p_action
    );
    l_elapsed_ms := (DBMS_UTILITY.GET_TIME - l_started) * 10;
    l_result_head := DBMS_LOB.SUBSTR(l_result, 32767, 1);
    SELECT RAWTOHEX(STANDARD_HASH(l_result_head, 'SHA256'))
      INTO l_result_hash
      FROM dual;

    IF p_action = 'showsql' THEN
      IF REGEXP_LIKE(LTRIM(l_result_head), '^(SELECT|WITH)[[:space:]]', 'i') THEN
        l_valid_sql := 'Y';
      ELSE
        l_valid_sql := 'N';
      END IF;
    END IF;

    DBMS_OUTPUT.PUT_LINE(
      'BENCHMARK|run=' || p_run_no
      || '|action=' || p_action
      || '|profile=' || p_profile_name
      || '|elapsed_ms=' || l_elapsed_ms
      || '|result_chars=' || DBMS_LOB.GETLENGTH(l_result)
      || '|valid_sql=' || l_valid_sql
      || '|result_sha256=' || l_result_hash
    );
  EXCEPTION
    WHEN OTHERS THEN
      l_elapsed_ms := (DBMS_UTILITY.GET_TIME - l_started) * 10;
      DBMS_OUTPUT.PUT_LINE(
        'BENCHMARK_ERROR|run=' || p_run_no
        || '|action=' || p_action
        || '|profile=' || p_profile_name
        || '|elapsed_ms=' || l_elapsed_ms
        || '|error=' || REPLACE(SUBSTR(SQLERRM, 1, 500), '|', '/')
      );
  END run_one;

  PROCEDURE run_pair(p_run_no IN PLS_INTEGER, p_action IN VARCHAR2) IS
  BEGIN
    IF MOD(p_run_no, 2) = 1 THEN
      run_one(p_run_no, p_action, c_annotation_profile);
      run_one(p_run_no, p_action, c_no_annotation_profile);
    ELSE
      run_one(p_run_no, p_action, c_no_annotation_profile);
      run_one(p_run_no, p_action, c_annotation_profile);
    END IF;
  END run_pair;
BEGIN
  DBMS_OUTPUT.PUT_LINE(
    'BENCHMARK_START|prompt_utf8_bytes=' ||
    UTL_RAW.LENGTH(UTL_I18N.STRING_TO_RAW(l_prompt, 'AL32UTF8'))
  );

  FOR run_no IN 1 .. 3 LOOP
    run_pair(run_no, 'showprompt');
  END LOOP;

  FOR run_no IN 1 .. 3 LOOP
    run_pair(run_no, 'showsql');
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('BENCHMARK_END');
END;
/

EXIT SUCCESS
