const TdPrompt = require('@tdprompt/td-prompt.js');
const GeminiClient = require('@tdprompt/genkit-client.js');
const GenkitModels = require('@tdprompt/genkit-models.js');

// Define the API models to test and report
// .....

// TdPrompt will run and benchmark the scenarios
(new TdPrompt(apiModels)).benchmark(function (params) {

    describe(`Restaurant orders agent - evaluating ${params?.model}`, function () {
        let geminiClient, prompt, json;

        // Setup current model from the list
        before(async function () {
            // Load prompt template, we use EJS for flexible parametrization
            // .....
        });

        describe('order creation', function () {
            // .....
        });

        describe('order updates', function () {
            // .....
        });

        describe('validate order state after updates', function () {
            describeAndValidateOrderItem('pepperoni pizza', 1, ['add pepper on top']);
            describeAndValidateOrderItem('cocacola', 1, ['ice']);
            describeAndValidateOrderItem('sprite', 1, ['no ice']);
            describeAndValidateOrderItem('nugget', 1);
            describeAndValidateOrderItem('chicken tender', 1);
            describeAndValidateOrderItem('ice cream', 2);
            describeAndValidateOrderItem('chocolate ice cream', 1, ['sprinkles']);
            describeAndValidateOrderItem('cheese cake', 2);
            describeAndValidateOrderItem('sandwich', 1, ['american cheese', 'mayo']);
        });
    });
});

// Helper functions
function describeAndValidateOrderItem(name, quantity, extras = []) {
    describe(`validate order-item of ${name}`, function () {
        let menuItem

        it(`order must contain ${name} item`, function () {
            menuItem = json?.data?.menuItems.find(item => item?.name?.toLowerCase() === name?.toLowerCase());

            // Validate order item naming and quantity
            assert.ok(menuItem, `order must contain ${name} item`);
        });

        it(`must contain quantity of ${quantity} ${name}`, function () {
            assert.equal(menuItem.quantity, quantity, `it must contain quantity of ${quantity} ${name}, instead it got ${menuItem.quantity}`);
        });

        it(`must be ${extras.length} extras on ${name}`, function () {
            assert.equal(menuItem.extras?.length || 0, extras.length, `it must return ${extras.length} extras, instead it got ${menuItem.extras?.length}`);
        });

        extras.forEach((extra, index) => {
            it(`must be a ${extra} extra on ${name}`, function () {
                assert.ok(menuItem.extras[index]?.description.toLowerCase().indexOf(extra.toLowerCase()) >= 0, `it must contain ${extra} extra`);
            });
        });
    });
}