/*
 * Copyright (c) 2019, 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.
 */

#define LOG_TAG "Util"

#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <android-base/logging.h>
#include <android-base/stringprintf.h>

#include <android/security/identity/ICredentialStore.h>

#include "Util.h"

namespace android {
namespace security {
namespace identity {

using ::android::base::StringPrintf;

Status halStatusToError(const Status& halStatus, int credStoreError) {
    string message = StringPrintf(
        "HAL failed with exception code %d (%s), service-specific error code %d, message '%s'",
        halStatus.exceptionCode(), Status::exceptionToString(halStatus.exceptionCode()).c_str(),
        halStatus.serviceSpecificErrorCode(), halStatus.exceptionMessage().c_str());
    return Status::fromServiceSpecificError(credStoreError, message.c_str());
}

Status halStatusToGenericError(const Status& halStatus) {
    return halStatusToError(halStatus, ICredentialStore::ERROR_GENERIC);
}

optional<vector<uint8_t>> fileGetContents(const string& path) {
    int fd = open(path.c_str(), O_RDONLY);
    if (fd == -1) {
        PLOG(ERROR) << "Error opening " << path;
        return {};
    }

    struct stat statbuf;
    if (fstat(fd, &statbuf) != 0) {
        PLOG(ERROR) << "Error statting " << path;
        close(fd);
        return {};
    }
    vector<uint8_t> data;
    data.resize(statbuf.st_size);

    uint8_t* p = data.data();
    size_t remaining = data.size();
    while (remaining > 0) {
        ssize_t numRead = TEMP_FAILURE_RETRY(read(fd, p, remaining));
        if (numRead <= 0) {
            PLOG(ERROR) << "Failed reading from '" << path << "'";
            close(fd);
            return {};
        }
        p += numRead;
        remaining -= numRead;
    }
    close(fd);

    return data;
}

bool fileSetContents(const string& path, const vector<uint8_t>& data) {
    char tempName[4096];
    int fd;

    string tempNameStr = path + ".XXXXXX";
    if (tempNameStr.size() >= sizeof tempName - 1) {
        LOG(ERROR) << "Path name too long";
        return false;
    }
    strncpy(tempName, tempNameStr.c_str(), sizeof tempName);

    fd = mkstemp(tempName);
    if (fd == -1) {
        PLOG(ERROR) << "Error creating temp file for '" << path << "'";
        return false;
    }

    const uint8_t* p = data.data();
    size_t remaining = data.size();
    while (remaining > 0) {
        ssize_t numWritten = TEMP_FAILURE_RETRY(write(fd, p, remaining));
        if (numWritten <= 0) {
            PLOG(ERROR) << "Failed writing into temp file for '" << path << "'";
            close(fd);
            return false;
        }
        p += numWritten;
        remaining -= numWritten;
    }

    if (TEMP_FAILURE_RETRY(fsync(fd))) {
        PLOG(ERROR) << "Failed fsyncing temp file for '" << path << "'";
        close(fd);
        return false;
    }
    close(fd);

    if (rename(tempName, path.c_str()) != 0) {
        PLOG(ERROR) << "Error renaming temp file for '" << path << "'";
        close(fd);
        return false;
    }

    return true;
}

}  // namespace identity
}  // namespace security
}  // namespace android
