/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "operation_table.h"

#include <keymaster/new>

#include <openssl/rand.h>

#include "openssl_err.h"
#include "operation.h"

namespace keymaster {

OperationTable::Entry::~Entry() {
    delete operation;
    operation = NULL;
    handle = 0;
}

keymaster_error_t OperationTable::Add(Operation* operation, const KeymasterContext& context,
                                      keymaster_operation_handle_t* op_handle) {
    if (!table_.get()) {
        table_.reset(new (std::nothrow) Entry[table_size_]);
        if (!table_.get())
            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
    }

    UniquePtr<Operation> op(operation);
    keymaster_error_t error = operation->CreateOperationHandle(context, op_handle);
    if (error != KM_ERROR_OK)
        return error;
    if (*op_handle == 0) {
        // Statistically this is vanishingly unlikely, which means if it ever happens in practice,
        // it indicates a broken RNG.
        return KM_ERROR_UNKNOWN_ERROR;
    }

    for (size_t i = 0; i < table_size_; ++i) {
        if (table_[i].operation == NULL) {
            table_[i].operation = op.release();
            table_[i].handle = *op_handle;
            return KM_ERROR_OK;
        }
    }
    return KM_ERROR_TOO_MANY_OPERATIONS;
}

Operation* OperationTable::Find(keymaster_operation_handle_t op_handle) {
    if (op_handle == 0)
        return NULL;

    if (!table_.get())
        return NULL;

    for (size_t i = 0; i < table_size_; ++i) {
        if (table_[i].handle == op_handle)
            return table_[i].operation;
    }
    return NULL;
}

bool OperationTable::Delete(keymaster_operation_handle_t op_handle) {
    if (!table_.get())
        return false;

    for (size_t i = 0; i < table_size_; ++i) {
        if (table_[i].handle == op_handle) {
            delete table_[i].operation;
            table_[i].operation = NULL;
            table_[i].handle = 0;
            return true;
        }
    }
    return false;
}

}  // namespace keymaster
