#!/usr/bin/env raku
use v6.d;

use WWW::OpenAI;

my %*SUB-MAIN-OPTS =
        :named-anywhere,
        # allow named variables at any location
        ;

#| Text processing using the OpenAI API.
multi sub openai-front(Str $text,                                #= Text to be processed or audio file name.
                       Str :$path = 'chat/completions',          #= Path, one of 'chat/completions', 'images/generations', 'images/edits', 'images/variations', 'moderations', 'audio/transcriptions', 'audio/translations', 'embeddings', or 'models'.
                       UInt :$n = 1,                             #= Number of completions or generations.
                       UInt :mt(:$max-tokens) = 100,             #= The maximum number of tokens to generate in the completion.
                       Str :m(:$model) is copy = 'Whatever',     #= Model.
                       Str :r(:$role) is copy = 'user',          #= Role.
                       Real :t(:$temperature) = 0.7,             #= Temperature.
                       Str :i(:$images) = '',                    #= Image URLs or file names separated with comma (',').
                       Str :l(:$language) = '',                  #= Language.
                       Str :$response-format = 'url',            #= The format in which the generated images are returned; one of 'url' or 'b64_json'.
                       Str :a(:$auth-key) is copy = 'Whatever',  #= Authorization key (to use OpenAI API.)
                       UInt :$timeout= 10,                       #= Timeout.
                       Str :f(:$format) is copy = 'Whatever',    #= Format of the result; one of "json", "hash", "values", or "Whatever".
                       Str :$method is copy = 'tiny',            #= Method for the HTTP POST query; one of "tiny" or "curl".
                       Str :$base-url is copy = 'Whatever',      #= URL of the Web API service.
                       ) {

    if $text.chars == 0 {
        note 'Nothing.';
        return;
    }

    if $base-url eq 'Whatever' { $base-url = openai-base-url; }

    if $auth-key eq 'Whatever' {
        if %*ENV<OPENAI_API_KEY>:exists {
            $auth-key = %*ENV<OPENAI_API_KEY>;
        } else {
            note 'Cannot find OpenAI authorization key. ' ~
                    'Please provide a valid key to the argument auth-key, or set the ENV variable OPENAI_API_KEY.';
            $auth-key = ''
        }
    }

    if $format.lc ∈ <v value auto whatever> { $format = 'values'; }

    my @imagesLocal = $images ?? $images.split(',', :skip-empty).map(*.trim).List !! Empty;

    my $res =
            openai-playground($text,
                    :$path,
                    model => $model eq 'Whatever' ?? Whatever !! $model,
                    role => $role eq 'Whatever' ?? Whatever !! $role,
                    :$n,
                    :$max-tokens,
                    :$response-format,
                    :$language,
                    :$temperature,
                    images => @imagesLocal,
                    :$auth-key,
                    :$timeout,
                    :$format,
                    :$method,
                    :$base-url);

    if $format.lc ∈ <hash raku> {
        say $res.raku;
    } else {
        say $res;
    }
}

multi sub MAIN
#= Command given as a sequence of words.
(*@words,
 Str :$path = 'chat/completions',          #= Path, one of 'chat/completions', 'images/generations', 'images/edits', 'images/variations', 'moderations', 'audio/transcriptions', 'audio/translations', 'embeddings', or 'models'.
 UInt :$n = 1,                             #= Number of completions or generations.
 UInt :mt(:$max-tokens) = 100,            #= The maximum number of tokens to generate in the completion.
 Str :m(:$model) is copy = 'Whatever',     #= Model.
 Str :r(:$role) is copy = 'user',          #= Role.
 Real :t(:$temperature) = 0.7,             #= Temperature.
 Str :i(:$images) = '',                    #= Image URLs or file names separated with comma (',').
 Str :l(:$language) = '',                  #= Language.
 Str :$response-format = 'url',            #= The format in which the generated images are returned; one of 'url' or 'b64_json'.
 Str :a(:$auth-key) is copy = 'Whatever',  #= Authorization key (to use OpenAI API.)
 UInt :$timeout= 10,                       #= Timeout.
 Str :f(:$format) is copy = 'Whatever',    #= Format of the result; one of "json", "hash", "values", or "Whatever".
 Str :$method is copy = 'tiny',            #= Method for the HTTP POST query; one of "tiny" or "curl".
 Str :$base-url is copy = 'Whatever',      #= URL of the Web API service.
 ) {
    return openai-front(@words.join(' ').Str, :$model, :$path, :$n, :$max-tokens, :$role, :$temperature, :$images, :$language, :$response-format, :$auth-key, :$timeout, :$format, :$method, :$base-url);
}