// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <efi/types.h>
#include <efi/protocol/device-path-to-text.h>
#include <efi/protocol/file.h>
#include <efi/protocol/simple-file-system.h>

#include <stdlib.h>
#include <string.h>
#include <printf.h>
#include <utils.h>

#define ERR_ENTRY(x) { #x, L"" #x }
typedef struct {
    const char* str;
    const char16_t* w_str;
} err_entry_t;

err_entry_t efi_error_labels[] = {
    ERR_ENTRY(EFI_SUCCESS),
    ERR_ENTRY(EFI_LOAD_ERROR),
    ERR_ENTRY(EFI_INVALID_PARAMETER),
    ERR_ENTRY(EFI_UNSUPPORTED),
    ERR_ENTRY(EFI_BAD_BUFFER_SIZE),
    ERR_ENTRY(EFI_BUFFER_TOO_SMALL),
    ERR_ENTRY(EFI_NOT_READY),
    ERR_ENTRY(EFI_DEVICE_ERROR),
    ERR_ENTRY(EFI_WRITE_PROTECTED),
    ERR_ENTRY(EFI_OUT_OF_RESOURCES),
    ERR_ENTRY(EFI_VOLUME_CORRUPTED),
    ERR_ENTRY(EFI_VOLUME_FULL),
    ERR_ENTRY(EFI_NO_MEDIA),
    ERR_ENTRY(EFI_MEDIA_CHANGED),
    ERR_ENTRY(EFI_NOT_FOUND),
    ERR_ENTRY(EFI_ACCESS_DENIED),
    ERR_ENTRY(EFI_NO_RESPONSE),
    ERR_ENTRY(EFI_NO_MAPPING),
    ERR_ENTRY(EFI_TIMEOUT),
    ERR_ENTRY(EFI_NOT_STARTED),
    ERR_ENTRY(EFI_ALREADY_STARTED),
    ERR_ENTRY(EFI_ABORTED),
    ERR_ENTRY(EFI_ICMP_ERROR),
    ERR_ENTRY(EFI_TFTP_ERROR),
    ERR_ENTRY(EFI_PROTOCOL_ERROR),
    ERR_ENTRY(EFI_INCOMPATIBLE_VERSION),
    ERR_ENTRY(EFI_SECURITY_VIOLATION),
    ERR_ENTRY(EFI_CRC_ERROR),
    ERR_ENTRY(EFI_END_OF_MEDIA),
    ERR_ENTRY(EFI_END_OF_FILE),
    ERR_ENTRY(EFI_INVALID_LANGUAGE),
    ERR_ENTRY(EFI_COMPROMISED_DATA),
};

efi_system_table* gSys;
efi_handle gImg;
efi_boot_services* gBS;
efi_simple_text_output_protocol* gConOut;

void InitGoodies(efi_handle img, efi_system_table* sys) {
    gSys = sys;
    gImg = img;
    gBS = sys->BootServices;
    gConOut = sys->ConOut;
}

void WaitAnyKey(void) {
    efi_simple_text_input_protocol* sii = gSys->ConIn;
    efi_input_key key;
    while (sii->ReadKeyStroke(sii, &key) != EFI_SUCCESS)
        ;
}

void Fatal(const char* msg, efi_status status) {
    printf("\nERROR: %s (%s)\n", msg, efi_strerror(status));
    WaitAnyKey();
    gBS->Exit(gImg, 1, 0, NULL);
}

char16_t* DevicePathToStr(efi_device_path_protocol* path) {
    efi_device_path_to_text_protocol* prot;
    efi_status status = gBS->LocateProtocol(&DevicePathToTextProtocol, NULL, (void**)&prot);
    if (EFI_ERROR(status)) {
        return NULL;
    }
    return prot->ConvertDevicePathToText(path, false, false);
}

int CompareGuid(efi_guid* guid1, efi_guid* guid2) {
    return memcmp(guid1, guid2, sizeof(efi_guid));
}

char16_t* HandleToString(efi_handle h) {
    efi_device_path_protocol* path;
    efi_status status = gBS->HandleProtocol(h, &DevicePathProtocol, (void*)&path);
    if (EFI_ERROR(status)) {
        char16_t* err;
        status = gBS->AllocatePool(EfiLoaderData, sizeof(L"<NoPath>"), (void**)&err);
        if (EFI_ERROR(status)) {
            return NULL;
        }
        gBS->CopyMem(err, L"<NoPath>", sizeof(L"<NoPath>"));
        return err;
    }
    char16_t* str = DevicePathToStr(path);
    if (str == NULL) {
        char16_t* err;
        status = gBS->AllocatePool(EfiLoaderData, sizeof(L"<NoString>"), (void**)&err);
        if (EFI_ERROR(status)) {
            return NULL;
        }
        gBS->CopyMem(err, L"<NoString>", sizeof(L"<NoString>"));
        return err;
    }
    return str;
}

efi_status OpenProtocol(efi_handle h, efi_guid* guid, void** ifc) {
    return gBS->OpenProtocol(h, guid, ifc, gImg, NULL,
                             EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
}

efi_status CloseProtocol(efi_handle h, efi_guid* guid) {
    return gBS->CloseProtocol(h, guid, gImg, NULL);
}

const char *efi_strerror(efi_status status)
{
    size_t i = (~EFI_ERROR_MASK & status);
    if (i < sizeof(efi_error_labels)/sizeof(efi_error_labels[0])) {
        return efi_error_labels[i].str;
    }

    return "<Unknown error>";
}

const char16_t* efi_wstrerror(efi_status status)
{
    size_t i = (~EFI_ERROR_MASK & status);
    if (i < sizeof(efi_error_labels)/sizeof(efi_error_labels[0])) {
        return efi_error_labels[i].w_str;
    }

    return L"<Unknown error>";
}

size_t strlen_16(char16_t* str)
{
    size_t len = 0;
    while (*(str + len) != '\0') {
        len++;
    }

    return len;
}
