/*
 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stddef.h>

#include <openssl/core.h>
#include "internal/cryptlib.h"
#include "internal/core.h"
#include "internal/property.h"
#include "internal/provider.h"

struct construct_data_st {
    OSSL_LIB_CTX *libctx;
    OSSL_METHOD_STORE *store;
    int operation_id;
    int force_store;
    OSSL_METHOD_CONSTRUCT_METHOD *mcm;
    void *mcm_data;
};

static int is_temporary_method_store(int no_store, void *cbdata)
{
    struct construct_data_st *data = cbdata;

    return no_store && !data->force_store;
}

static int ossl_method_construct_precondition(OSSL_PROVIDER *provider,
                                              int operation_id, int no_store,
                                              void *cbdata, int *result)
{
    if (!ossl_assert(result != NULL)) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    /* Assume that no bits are set */
    *result = 0;

    /* No flag bits for temporary stores */
    if (!is_temporary_method_store(no_store, cbdata)
        && !ossl_provider_test_operation_bit(provider, operation_id, result))
        return 0;

    /*
     * The result we get tells if methods have already been constructed.
     * However, we want to tell whether construction should happen (true)
     * or not (false), which is the opposite of what we got.
     */
    *result = !*result;

    return 1;
}

static int ossl_method_construct_postcondition(OSSL_PROVIDER *provider,
                                               int operation_id, int no_store,
                                               void *cbdata, int *result)
{
    if (!ossl_assert(result != NULL)) {
        ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    *result = 1;

    /* No flag bits for temporary stores */
    return is_temporary_method_store(no_store, cbdata)
        || ossl_provider_set_operation_bit(provider, operation_id);
}

static void ossl_method_construct_this(OSSL_PROVIDER *provider,
                                       const OSSL_ALGORITHM *algo,
                                       int no_store, void *cbdata)
{
    struct construct_data_st *data = cbdata;
    void *method = NULL;

    if ((method = data->mcm->construct(algo, provider, data->mcm_data))
        == NULL)
        return;

    /*
     * Note regarding putting the method in stores:
     *
     * we don't need to care if it actually got in or not here.
     * If it didn't get in, it will simply not be available when
     * ossl_method_construct() tries to get it from the store.
     *
     * It is *expected* that the put function increments the refcnt
     * of the passed method.
     */

    if (!is_temporary_method_store(no_store, data)) {
        /* If we haven't been told not to store, add to the global store */
        data->mcm->put(NULL, method, provider, algo->algorithm_names,
                       algo->property_definition, data->mcm_data);
    } else {
        /*
         * If we have been told not to store the method "permanently", we
         * ask for a temporary store, and store the method there.
         * The owner of |data->mcm| is completely responsible for managing
         * that temporary store.
         */
        if ((data->store = data->mcm->get_tmp_store(data->mcm_data)) == NULL)
            return;

        data->mcm->put(data->store, method, provider, algo->algorithm_names,
                       algo->property_definition, data->mcm_data);
    }

    /* refcnt-- because we're dropping the reference */
    data->mcm->destruct(method, data->mcm_data);
}

void *ossl_method_construct(OSSL_LIB_CTX *libctx, int operation_id,
                            OSSL_PROVIDER **provider_rw, int force_store,
                            OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data)
{
    void *method = NULL;

    if ((method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw,
                           mcm_data)) == NULL) {
        OSSL_PROVIDER *provider = provider_rw != NULL ? *provider_rw : NULL;
        struct construct_data_st cbdata;

        cbdata.store = NULL;
        cbdata.force_store = force_store;
        cbdata.mcm = mcm;
        cbdata.mcm_data = mcm_data;
        ossl_algorithm_do_all(libctx, operation_id, provider,
                              ossl_method_construct_precondition,
                              ossl_method_construct_this,
                              ossl_method_construct_postcondition,
                              &cbdata);

        /* If there is a temporary store, try there first */
        if (cbdata.store != NULL)
            method = mcm->get(cbdata.store, (const OSSL_PROVIDER **)provider_rw,
                              mcm_data);

        /* If no method was found yet, try the global store */
        if (method == NULL)
            method = mcm->get(NULL, (const OSSL_PROVIDER **)provider_rw, mcm_data);
    }

    return method;
}
