// 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 <xefi.h>

xefi_global xefi_global_state;

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

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

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

char16_t* xefi_devpath_to_str(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 xefi_cmp_guid(efi_guid* guid1, efi_guid* guid2) {
    return memcmp(guid1, guid2, sizeof(efi_guid));
}

char16_t* xefi_handle_to_str(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 = xefi_devpath_to_str(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 xefi_open_protocol(efi_handle h, efi_guid* guid, void** ifc) {
    return gBS->OpenProtocol(h, guid, ifc, gImg, NULL,
                             EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
}

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

const char *xefi_strerror(efi_status status) {
    switch (status) {
#define ERR_ENTRY(x) \
    case x: {        \
        return #x;   \
    }
        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);
        ERR_ENTRY(EFI_IP_ADDRESS_CONFLICT);
        ERR_ENTRY(EFI_HTTP_ERROR);
#undef ERR_ENTRY
    }

    return "<Unknown error>";
}

const char16_t* xefi_wstrerror(efi_status status) {
    switch (status) {
#define ERR_ENTRY(x)     \
    case x: {            \
        return L"" #x;   \
    }
        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);
        ERR_ENTRY(EFI_IP_ADDRESS_CONFLICT);
        ERR_ENTRY(EFI_HTTP_ERROR);
#undef ERR_ENTRY
    }

    return L"<Unknown error>";
}

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

    return len;
}
