create or replace FUNCTION fnc_26ai_embed_image_cohere (image_name in VARCHAR2, 
                                                   image_blob in BLOB, 
                                                   oci_cred IN VARCHAR2 default 'OCI_CRED',
                                                   p_comp_id in varchar2,
                                                   p_code_mode in number default 1 ) 
return clob 
as
/*

  Criado por: fernando.leal@oracle.com
  Data: Oct/2025
  Objetivo: demonstrar casos de uso do Oracle AI Database 26ai

  v1 - embedding de imagnes com Cohere On-Demand - leal

*/

    -- modelos: https://docs.oracle.com/en-us/iaas/Content/generative-ai/pretrained-models.htm
    -- cuidado com pre requisito (1)
    gen_ai_endpoint     varchar2(500) := 'https://inference.generativeai.us-chicago-1.oci.oraclecloud.com';
    gen_ai_model        varchar2(500) := 'cohere.embed-v4.0';

    embed_resp          dbms_cloud_types.RESP;

    file_extension      VARCHAR2(5);
    base64_image        CLOB := NULL;
    invalid_image       EXCEPTION;
    image_too_big       EXCEPTION;
    request_json_part1  CLOB;
    request_json_part2  CLOB;
    request_body        BLOB;
    v_vector vector;
BEGIN

 if p_code_mode = 1 then

    -- get file extension from file name and validate
    file_extension :=   lower(regexp_replace(image_name, '.*\.([a-zA-Z0-9]+)$', '\1')) ;

    -- create temp blob
    dbms_lob.createtemporary(request_body, FALSE);
    -- base64 encode the image
    base64_image := APEX_WEB_SERVICE.BLOB2CLOBBASE64(image_blob,'N','N');

	-- validate size of base64 image, must be less than 5 mb
  --  if length(base64_image) > 5242880 then
    --    raise image_too_big;
  --  end if;

	-- define beginning of request payload    
    request_json_part1 := to_clob('{"inputs": ["data:image/' || file_extension || ';base64,');

	-- define ending of request payload    
    request_json_part2 := to_clob('"],
                                  "servingMode": {
                                    "servingType": "ON_DEMAND",
                                    "modelId": "'  || gen_ai_model || '"
                                  },
                                  "truncate": "NONE",
                                  "inputType": "IMAGE",
                                  "compartmentId": "' || p_comp_id || '"}'); 

    -- append part1 json to request blob
    dbms_lob.append(request_body, apex_util.clob_to_blob(p_clob => request_json_part1,p_charset => 'AL32UTF8'));
    -- append base64 image to request blob
    dbms_lob.append(request_body, apex_util.clob_to_blob(p_clob => base64_image,p_charset => 'AL32UTF8'));
    -- append part2 json to request blob
    dbms_lob.append(request_body, apex_util.clob_to_blob(p_clob => request_json_part2,p_charset => 'AL32UTF8'));
    -- Call GenAI Embed Service
    embed_resp := dbms_cloud.send_request(
        credential_name => oci_cred,
        uri             => gen_ai_endpoint || '/20231130/actions/embedText',
        method          => dbms_cloud.METHOD_POST,
        body            => request_body
    );
    -- free temp blob
    dbms_lob.freetemporary(request_body);
    -- return embed reponse
    RETURN dbms_cloud.get_response_text(embed_resp);


  elsif p_code_mode = 2 then
  

    RETURN to_clob( DBMS_VECTOR.UTL_TO_EMBEDDING(
        image_blob,
        'image',
        JSON('{
            "provider": "OCIGenAI",
            "credential_name": "' || oci_cred || '",
            "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
            "model": "' || gen_ai_model || '"
        }')
    )  ) ;


  elsif p_code_mode = 3 then

    SELECT VECTOR_EMBEDDING( VIT_BASE_PATCH16_224  USING  image_blob  AS data   ) as embedding 
	into v_vector;

    return to_clob( v_vector );
 
  elsif p_code_mode = 4 then

  /*  https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/onnx-pipeline-models-multi-modal-embedding.html
  
        begin
         DBMS_VECTOR.LOAD_ONNX_MODEL_CLOUD(
            model_name => 'CLIP_VIT_LARGE_PATCH14_IMG',
            credential => 'OCI_CRED', 
            uri => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/p/py9iUuDsr_WFX6L0ziRvgPkYIhTYsdTgq6SF9S1j1pJWkS67jx2lXWqXz4cZkdDP/n/idi1o0a010nx/b/bucket-database-26ai/o/clip-vit-large-patch14_img.onnx',
            metadata => JSON('{"function" : "embedding", "embeddingOutput" : "embedding" , "input": {"input": ["DATA"]}}')
        );

        DBMS_VECTOR.LOAD_ONNX_MODEL_CLOUD(
            model_name => 'CLIP_VIT_LARGE_PATCH14_TXT',
            credential => 'OCI_CRED', 
            uri => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/p/py9iUuDsr_WFX6L0ziRvgPkYIhTYsdTgq6SF9S1j1pJWkS67jx2lXWqXz4cZkdDP/n/idi1o0a010nx/b/bucket-database-26ai/o/clip-vit-large-patch14_txt.onnx',
            metadata => JSON('{"function" : "embedding", "embeddingOutput" : "embedding" , "input": {"input": ["DATA"]}}')
        );

        END;
  */

    --   select DBMS_VECTOR.UTL_TO_EMBEDDING(
    --    image_blob ,
    --     'image',
    --      json('{"provider":"database", "model":"CLIP_VIT_LARGE_PATCH14_IMG"}') )
	-- into v_vector;

     SELECT VECTOR_EMBEDDING( CLIP_VIT_LARGE_PATCH14_IMG  USING  image_blob  AS data   ) as embedding 
	into v_vector;

    return to_clob( v_vector );
  end if;

EXCEPTION
    WHEN invalid_image THEN
        RAISE_APPLICATION_ERROR(-20001,'Invalid Image Extension, must be png,jpg,jpeg: ' || image_name);        
    WHEN image_too_big THEN
        RAISE_APPLICATION_ERROR(-20002,'Base64 Image Over 5 MB: ' || length(base64_image) || ' - ' || image_name);                
END;
/