/*
 * 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 "credstore"

#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
