/*
 * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */

#include "class_forwards.hpp"

#include "boilerplate.hpp"
#include "gibberish.hpp"
#include "compute.hpp"
#include "string_ops.hpp"
#include "data_blocks.hpp"
#include "psa_asset.hpp"
#include "find_or_create_asset.hpp"
#include "template_line.hpp"
#include "tf_fuzz.hpp"
#include "crypto_asset.hpp"
#include "psa_call.hpp"
#include "sst_call.hpp"
#include "sst_asset.hpp"
#include "crypto_asset.hpp"
#include "variables.hpp"



/**********************************************************************************
   Methods of class sst_set_call follow:
**********************************************************************************/

sst_set_call::sst_set_call (tf_fuzz_info *test_state,    // (constructor)
                            long &call_ser_no,
                            asset_search how_asset_found)
                                : sst_call(test_state, call_ser_no, how_asset_found)
{
    // Copy the boilerplate text into local buffers:
    prep_code.assign ("");  // will fill in, depending upon template line content
    call_code.assign (test_state->bplate->bplate_string[set_sst_call]);
    check_code.assign (test_state->bplate->bplate_string[set_sst_check]);
    call_description = "SST-set call";
}
sst_set_call::~sst_set_call (void)
{
    return;  // just to have something to pin a breakpoint onto
}

bool sst_set_call::copy_call_to_asset (void)
{
    vector<psa_asset*>::iterator found_asset;

    found_asset = resolve_asset (yes_create_asset, psa_asset_usage::all);
    // Copy over everything relevant:
    if (asset_info.how_asset_found != asset_search::not_found) {
        asset_info.the_asset = reinterpret_cast<sst_asset*>(*found_asset);
            /* Note:  The vector is base-class, but the assets in this list
                      themselves *really are* sst_asset-type objects. */
        int i = asset_info.the_asset->set_data.n_set_vars;  // save this
        asset_info.the_asset->set_data = set_data;  // TO DO:  does this make sense?!
        asset_info.the_asset->set_data.n_set_vars = set_data.n_set_vars = ++i;
        asset_info.the_asset->set_data.flags_string.assign (set_data.flags_string);
        if (asset_info.how_asset_found == asset_search::created_new) {
            asset_info.the_asset->asset_info.name_specified = asset_info.name_specified;
            asset_info.the_asset->asset_info.set_name (asset_info.get_name());
            asset_info.the_asset->asset_info.asset_ser_no = asset_info.asset_ser_no;
            asset_info.the_asset->asset_info.id_n = asset_info.id_n;
        }
    }
    return true;
}

bool sst_set_call::copy_asset_to_call (void)
{
    // Get updated asset info from the asset:
    asset_info.asset_ser_no = asset_info.the_asset->asset_info.asset_ser_no;
    asset_info.id_n = asset_info.the_asset->asset_info.id_n;
    exp_data.n_exp_vars = asset_info.the_asset->exp_data.n_exp_vars;
    exp_data.data = asset_info.the_asset->exp_data.data;
    return true;
}

void sst_set_call::fill_in_prep_code (void)
{
    string var_name, length_var_name, var_name_suffix, length_var_name_suffix,
           temp_string;
    vector<variable_info>::iterator assign_variable;

    if (assign_data_var_specified) {
        var_name.assign (assign_data_var + "_data");
        length_var_name.assign (assign_data_var + "_length");
        /* If actual-data variable doesn't already exist, create variable tracker,
           and write declaration for it: */
        assign_variable = test_state->find_var (assign_data_var);
        if (assign_variable == test_state->variable.end()) {
            // No such variable exists, so:
            test_state->make_var (assign_data_var);
            assign_variable = test_state->find_var (assign_data_var);
            prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
            find_replace_1st ("$var", var_name, prep_code);
            temp_string = (char *) assign_variable->value;
            find_replace_1st ("$init", temp_string, prep_code);
            // Actual-data length:
            prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
            find_replace_1st ("$var", length_var_name, prep_code);
            find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
            // Offset (always 0 for now):
            find_replace_1st ("$offset", "0", prep_code);
        }
    } else {
        // Single string of two lines declaring string data and its length:
        var_name_suffix = "_set_data";
        length_var_name_suffix = "_set_length";
        if (set_data.n_set_vars > 0) {
            var_name_suffix += "_" + to_string(set_data.n_set_vars);
            length_var_name_suffix += "_" + to_string(set_data.n_set_vars);
            // We'll increment set_data.n_set_vars after we fill in the call itself.
        }
        var_name.assign (asset_info.get_name() + var_name_suffix);
        length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
        prep_code = test_state->bplate->bplate_string[declare_string];
        find_replace_1st ("$var", var_name, prep_code);
        find_replace_1st ("$init", set_data.get(), prep_code);
        temp_string.assign (test_state->bplate->bplate_string[declare_int]);
        find_replace_1st ("static int", "static uint32_t", temp_string);
        prep_code.append (temp_string);
        find_replace_1st ("$var", length_var_name, prep_code);
        find_replace_1st ("$init", to_string(set_data.get().length()), prep_code);
    }
}

void sst_set_call::fill_in_command (void)
{
    string var_name, length_var_name, var_name_suffix, length_var_name_suffix,
           temp_string;

    // Fill in preceding comment:
    if (asset_info.how_asset_found == asset_search::created_new) {
        find_replace_1st ("$op", "Creating", call_code);
    } else {
        find_replace_1st ("$op", "Resetting", call_code);
    }
    if (asset_info.name_specified) {
        find_replace_1st ("$description", "\"" + asset_info.get_name() + ",\"",
                          call_code);
    } else {
        find_replace_1st ("$description",
                          "UID = " + to_string((long) asset_info.id_n), call_code);
    }
    if (set_data.string_specified) {
        find_replace_1st ("$data_source",
                          "\"" + set_data.get().substr (0, 10) + "...\"",
                          call_code);
    } else if (set_data.file_specified) {
        find_replace_1st ("$data_source", "from file " + set_data.file_path,
                          call_code);
    } else {
        find_replace_1st (" $data_source", "", call_code);
    }
    // Fill in the PSA command itself:
    if (assign_data_var_specified) {
        var_name.assign (assign_data_var + "_data");
        length_var_name.assign (assign_data_var + "_length");
    } else {
        var_name_suffix = "_set_data";
        if (set_data.n_set_vars > 0) {
            var_name_suffix += "_" + to_string(set_data.n_set_vars);
        }
        var_name.assign (asset_info.get_name() + var_name_suffix);
        length_var_name_suffix = "_set_length";
        if (set_data.n_set_vars > 0) {
            length_var_name_suffix += "_" + to_string(set_data.n_set_vars);
        }
        length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
    }
    find_replace_1st ("$data", var_name, call_code);
    find_replace_1st ("$flags", set_data.flags_string, call_code);
    string id_string = to_string((long) asset_info.id_n);
    find_replace_1st ("$uid", id_string, call_code);
    find_replace_1st ("$length", length_var_name, call_code);
    // Figure out what expected results:
    if (   set_data.flags_string == "PSA_STORAGE_FLAG_WRITE_ONCE"
        && set_data.n_set_vars > 0) {
        exp_data.pf_specified = true;
        exp_data.pf_result_string = "PSA_ERROR_NOT_PERMITTED";
    }
    calc_result_code();
}

/**********************************************************************************
   End of methods of class sst_set_call.
**********************************************************************************/


/**********************************************************************************
   Methods of class sst_get_call follow:
**********************************************************************************/

sst_get_call::sst_get_call (tf_fuzz_info *test_state,    // (constructor)
                            long &call_ser_no,
                            asset_search how_asset_found)
                                 : sst_call(test_state, call_ser_no, how_asset_found)
{
    // Copy the boilerplate text into local buffers:
    prep_code.assign ("");
    call_code.assign (test_state->bplate->bplate_string[get_sst_call]);
    check_code.assign ("");
        // depends upon the particular usage;  will get it in fill_in_command()
    call_description = "SST-get call";
}
sst_get_call::~sst_get_call (void)
{
    return;  // just to have something to pin a breakpoint onto
}

bool sst_get_call::copy_call_to_asset (void)
{
    vector<psa_asset*>::iterator found_asset;

    found_asset = resolve_asset (dont_create_asset, psa_asset_usage::active);
    if (asset_info.how_asset_found != asset_search::not_found) {
        // will be found for set calls, but not necessarily others
        asset_info.the_asset = reinterpret_cast<sst_asset*>(*found_asset);
           // Note:  Vector is of base-class type, but the assets *are* sst_asset.
        /* Locating the asset is all we need to do here;  copy_asset_to_call() will
           do the rest. */
    }
    return true;
    // TODO:  Shouldn't data be copied over?
}

bool sst_get_call::copy_asset_to_call (void)
{
    if (asset_info.the_asset != nullptr) {
        // will be found for set calls, but not necessarily others
        set_data.string_specified = asset_info.the_asset->set_data.string_specified;
        set_data.file_specified = asset_info.the_asset->set_data.file_specified;
        set_data.set (asset_info.the_asset->set_data.get());
        set_data.flags_string = asset_info.the_asset->set_data.flags_string;
        asset_info.id_n = asset_info.the_asset->asset_info.id_n;
        asset_info.asset_ser_no = asset_info.the_asset->asset_info.asset_ser_no;
        asset_info.name_specified = asset_info.the_asset->asset_info.name_specified;
        asset_info.the_asset->exp_data.n_exp_vars++;
        exp_data.n_exp_vars = asset_info.the_asset->exp_data.n_exp_vars;
    }
    return true;
}

void sst_get_call::fill_in_prep_code (void)
{
    string var_base, var_name, length_var_name, temp_string, var_name_suffix,
           expected;
    vector<variable_info>::iterator act_variable, exp_variable;

    if (!(print_data || hash_data)) {
        // Checking asset data verbatim against expected, so:
        if (exp_data.data_var_specified) {
            // Template specified a variable name to "check" against;  use that:
            var_base.assign (exp_data.data_var);
            exp_variable = test_state->find_var (var_base);
            if (exp_variable == test_state->variable.end()) {
                test_state->make_var (var_base);
                exp_variable = test_state->find_var (var_base);
                var_name = var_base + "_data";
                prep_code.append (test_state->bplate->bplate_string[declare_string]);
                find_replace_1st ("$var", var_name, prep_code);
                temp_string = (char *) exp_variable->value;
                find_replace_1st ("$init", temp_string, prep_code);
                // Expected-data length:
                temp_string.assign (test_state->bplate->bplate_string[declare_int]);
                find_replace_1st ("static int", "static size_t", temp_string);
            }
        } else {
            if (exp_data.data_specified) {
                // Checking against literal expected data:
                expected.assign (exp_data.data);
            } else {
                // Check against what we believe the asset to contain:
                expected.assign (set_data.get());
            }
            var_name_suffix = "_exp_data";
            if (exp_data.n_exp_vars > 0) {
                var_name_suffix =
                    var_name_suffix + "_" + to_string(exp_data.n_exp_vars);
            }
            var_name.assign (asset_info.get_name() + var_name_suffix);
            prep_code.assign(test_state->bplate->bplate_string[declare_string]);
            find_replace_1st("$var", var_name, prep_code);
            find_replace_1st("$init", expected, prep_code);
        }
    }
    // Actual data:
    if (assign_data_var_specified) {
        var_base.assign (assign_data_var);
    } else {
        var_base.assign (asset_info.get_name() + "_act");
    }
    var_name.assign (var_base + "_data");
    length_var_name.assign (var_base + "_length");
    /* If actual-data variable doesn't already exist, create variable tracker,
       and write declaration for it: */
    act_variable = test_state->find_var (var_base);
    if (act_variable == test_state->variable.end()) {
        test_state->make_var (var_base);
        act_variable = test_state->find_var (var_base);
        prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
        find_replace_1st ("$var", var_name, prep_code);
        temp_string = (char *) act_variable->value;
        find_replace_1st ("$init", temp_string, prep_code);
        // Actual-data length:
        temp_string.assign (test_state->bplate->bplate_string[declare_int]);
        find_replace_1st ("static int", "static size_t", temp_string);
        prep_code.append (temp_string);
        find_replace_1st ("$var", length_var_name, prep_code);
        find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
        // Offset (always 0 for now):
        find_replace_1st ("$offset", "0", prep_code);
    }
    // If hashing the (actual) data, then create a variable for that:
    if (hash_data && !act_variable->hash_declared) {
        var_name = var_base + "_hash";
        prep_code.append (test_state->bplate->bplate_string[declare_generic]);
            // where to put the hash of the data
        find_replace_1st ("$type", "uint32_t", prep_code);
        find_replace_1st ("$var", var_name, prep_code);
        find_replace_1st ("$init", "0", prep_code);  // for now...
        act_variable->hash_declared = true;
    }
}

void sst_get_call::fill_in_command (void)
{
    string exp_var_name, act_var_name, act_data_length, hash_var_name,
    id_string, var_name_suffix;

/* TODO:  Flesh-out/fix this (it was a good try/start, but not quite right):
    // Fill in preceding comment:
    if (asset_info.how_asset_found == asset_search::created_new) {
        find_replace_1st ("$op", "Creating", call_code);
    } else {
        find_replace_1st ("$op", "Resetting", call_code);
    }
    if (asset_info.name_specified) {
        find_replace_1st ("$description", "\"" + asset_info.get_name() + ",\"",
                          call_code);
    } else {
        find_replace_1st ("$description",
                          "UID = " + to_string((long) asset_info.id_n), call_code);
    }
    if (set_data.string_specified) {
        find_replace_1st ("$data_source",
                          "\"" + data.substr (0, 10) + "...\"",
                          call_code);
    } else if (set_data.file_specified) {
        find_replace_1st ("$data_source", "from file " + set_data.file_path,
                          call_code);
    } else {
        find_replace_1st (" $data_source", "", call_code);
    }
*/    // Fill in the call itself:
    if (print_data || hash_data) {
        // Dump to variable;  no data-check code needed:
        check_code.assign (test_state->bplate->bplate_string[get_sst_check]);
    } else {
        // Check either against literal or variable, so need data-check code too:
        check_code.assign (test_state->bplate->bplate_string[get_sst_check_all]);
    }
    /* Note:  Can fill in the check code identically between the dump-to-variable
              and check-data cases, because the boilerplate for the former is just an
              abbreviated version of the latter.  The find_replace_1st() calls for
              the check-data stuff will just simply not have any effect. */
    if (exp_data.data_var_specified) {
        // Check against data in variable:
        exp_var_name.assign (exp_data.data_var + "_data");
    } else {
        var_name_suffix = "_exp_data";
        if (exp_data.n_exp_vars > 0) {
            var_name_suffix =
                var_name_suffix + "_" + to_string(exp_data.n_exp_vars);
        }
        exp_var_name.assign (asset_info.get_name() + var_name_suffix);
    }
    if (assign_data_var_specified) {
        act_var_name.assign (assign_data_var + "_data");
        act_data_length.assign (assign_data_var + "_length");
    } else {
        act_var_name.assign (asset_info.get_name() + "_act_data");
        act_data_length.assign (asset_info.get_name() + "_act_length");
    }

    id_string = to_string((long) asset_info.id_n);
    // Fill in the PSA command itself:
    find_replace_1st ("$uid", id_string, call_code);
    find_replace_all ("$length", to_string(set_data.get().length()), call_code);
    find_replace_1st ("$offset", to_string(set_data.data_offset), call_code);
    find_replace_1st ("$exp_data", exp_var_name, call_code);
    find_replace_all ("$act_data", act_var_name, call_code);
    find_replace_all ("$act_length", act_data_length, call_code);
    // Perform most of the same substitutions in the check_code:
// TODO:  Make data checks contingent upon the PSA call itself passing?
    find_replace_1st ("$offset", "0", check_code);
    find_replace_1st ("$exp_data", exp_var_name, check_code);
    find_replace_all ("$act_data", act_var_name, check_code);
    find_replace_all ("$length", act_data_length, check_code);
    if (print_data) {
        check_code.append (test_state->bplate->bplate_string[test_log]);
        find_replace_1st ("$message", act_var_name, check_code);
    }
    if (hash_data) {
        hash_var_name.assign (asset_info.get_name() + "_act_hash");
            // this is where to put the hash of the data
        check_code.append (test_state->bplate->bplate_string[get_sst_hash]);
        find_replace_all ("$act_data_var", act_var_name, check_code);
        find_replace_all ("$hash_var", hash_var_name, check_code);
    }
    // Figure out what expected results:
    calc_result_code();  // this only fills $expect check_code
    // Fill in expected data, actual data, and length:
}

/**********************************************************************************
   End of methods of class sst_get_call.
**********************************************************************************/


/**********************************************************************************
   Methods of class sst_remove_call follow:
**********************************************************************************/

sst_remove_call::sst_remove_call (tf_fuzz_info *test_state,    // (constructor)
                                  long &call_ser_no,
                                  asset_search how_asset_found)
                                 : sst_call(test_state, call_ser_no, how_asset_found)
{
    // Copy the boilerplate text into local buffers:
    prep_code.assign ("");
    call_code.assign (test_state->bplate->bplate_string[remove_sst]);
    check_code.assign (test_state->bplate->bplate_string[remove_sst_check]);
    call_description = "SST-remove call";
}
sst_remove_call::~sst_remove_call (void)
{
    return;  // just to have something to pin a breakpoint onto
}

bool sst_remove_call::copy_call_to_asset (void)
{
    vector<psa_asset*>::iterator found_asset;

    found_asset = resolve_asset (dont_create_asset, psa_asset_usage::all);
    if (asset_info.how_asset_found != asset_search::not_found) {
        asset_info.the_asset = reinterpret_cast<sst_asset*>(*found_asset);
           // Note:  Vector is of base-class type, but the assets *are* sst_asset.
        if (asset_info.how_asset_found == asset_search::found_active) {
            // Delete asset;  move it from active vector to deleted vector:
            test_state->deleted_sst_asset.push_back (asset_info.the_asset);
            test_state->active_sst_asset.erase (found_asset);
        }  /* if not active, we'll deem the call expected to fail. */
    }
    return true;
}

bool sst_remove_call::copy_asset_to_call (void)
{
    if (asset_info.the_asset != nullptr) {
        set_data.string_specified = asset_info.the_asset->set_data.string_specified;
        set_data.file_specified = asset_info.the_asset->set_data.file_specified;
        set_data.flags_string = asset_info.the_asset->set_data.flags_string;
        asset_info.id_n = asset_info.the_asset->asset_info.id_n;
        asset_info.name_specified = asset_info.the_asset->asset_info.name_specified;
    }
    return true;
}

void sst_remove_call::fill_in_prep_code (void)
{
    // No prep-code.
    return;  // just to have something to pin a breakpoint onto
}

void sst_remove_call::fill_in_command (void)
{
    // Fill in the call:
    string id_string = to_string((long) asset_info.id_n);
    find_replace_1st ("$uid", id_string, call_code);
    // Fill in expected results:
    calc_result_code();  // this only fills $expect check_code
}

/**********************************************************************************
   End of methods of class sst_remove_call.
**********************************************************************************/

