/*
 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 *
 * This software is dual-licensed to you under the MIT License (MIT) and
 * the Universal Permissive License (UPL). See the LICENSE file in the root
 * directory for license terms. You may choose either license, or both.
 */

#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include "iotcs_port_system.h"
#include "iotcs_port_diagnostic.h"
#include "EthernetInterface.h"
#include "lwip/snmp.h"
#include "SDFileSystem.h"
#include "util/util.h"

#include "log/log.h"
#define IOTCSP_MODULE_LOG_CHANNEL LOG_CHANNEL_PORT_DIAG
#include "log/log_template.h"

#define SD_CARD_SECTOR_SIZE ((uint32_t)512)

int iotcs_port_get_ip_address(char* out_buffer, int out_buffer_length) {
    char *ip_addr;

    ip_addr = EthernetInterface::getIPAddress();
    if (ip_addr) {
        if (strnlen(ip_addr, out_buffer_length) < out_buffer_length) {
            return util_safe_snprintf(out_buffer, out_buffer_length, "%s", ip_addr);
        } else {
            LOG_ERRS("Buffer length is too small for ip address.");
        }
    }
    return -1;
}

int iotcs_port_get_mac_address(char* out_buffer, int out_buffer_length) {
    char *mac_addr;

    mac_addr = EthernetInterface::getMACAddress();
    if (mac_addr) {
        if (strnlen(mac_addr, out_buffer_length) < out_buffer_length) {
            return util_safe_snprintf(out_buffer, out_buffer_length, "%s", mac_addr);
        } else {
            LOG_ERRS("Buffer length is too small for mac address.");
        }
    }
    return -1;
}

const char* iotcs_port_get_version(void) {

    return "ARM mbed Library 1.1 release";
}

uint64_t iotcs_port_get_total_disk_space(void) {
    uint64_t total_size; // in bytes
    DWORD free_clust;
    FATFS *fs;

    // get volume information and free clusters of default drive
    if (FR_OK == f_getfree("", &free_clust, &fs)) {
        total_size = ((uint64_t) (fs->n_fatent - 2)) * fs->csize;
        total_size = total_size * SD_CARD_SECTOR_SIZE;

        return total_size;
    }

    return (uint64_t) - 1;
}

uint64_t iotcs_port_get_free_disk_space(void) {
    uint64_t free_size; // in bytes
    DWORD free_clust;
    FATFS *fs;

    // get volume information and free clusters of default drive
    if (FR_OK == f_getfree("", &free_clust, &fs)) {
        free_size = ((uint64_t) free_clust) * fs->csize;
        free_size = free_size * SD_CARD_SECTOR_SIZE;

        return free_size;
    }

    return (uint64_t) - 1;
}
