/*
 * Copyright (C) 2017 Team Win Recovery 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.
 */

/* To the best of my knowledge there is no native implementation for
 * Weaver so I made this by looking at the IWeaver.h file that gets
 * compiled by the build system. I took the information from this header
 * file and looked at keymaster source to get an idea of the proper way
 * to write the functions.
 */

#include "Weaver1.h"

//#include <android-base/logging.h>
#include <keystore/keymaster_tags.h>
#include <keystore/authorization_set.h>
#include <keystore/keystore_hidl_support.h>

#include <android/hardware/weaver/1.0/IWeaver.h>

#include <iostream>
#define ERROR 1
#define LOG(x) std::cout

using namespace android::hardware::weaver;
using android::hardware::hidl_string;
using ::android::hardware::weaver::V1_0::IWeaver;
using ::android::hardware::weaver::V1_0::WeaverConfig;
using ::android::hardware::weaver::V1_0::WeaverReadStatus;
using ::android::hardware::weaver::V1_0::WeaverReadResponse;
using ::android::hardware::weaver::V1_0::WeaverStatus;
using ::android::hardware::Return;
using ::android::sp;

namespace android {
namespace vold {

Weaver::Weaver() {
	mDevice = ::android::hardware::weaver::V1_0::IWeaver::getService();
	GottenConfig = false;
}

bool Weaver::GetConfig() {
	if (GottenConfig)
		return true;

	WeaverStatus status;
	WeaverConfig cfg;

	bool callbackCalled = false;
	auto ret = mDevice->getConfig([&](WeaverStatus s, WeaverConfig c) {
		callbackCalled = true;
		status = s;
		cfg = c;
	});
	if (ret.isOk() && callbackCalled && status == WeaverStatus::OK) {
		config = cfg;
		GottenConfig = true;
		return true;
	}
	return false;
}

bool Weaver::GetSlots(uint32_t* slots) {
	if (!GetConfig())
		return false;
	*slots = config.slots;
	return true;
}

bool Weaver::GetKeySize(uint32_t* keySize) {
	if (!GetConfig())
		return false;
	*keySize = config.keySize;
	return true;
}

bool Weaver::GetValueSize(uint32_t* valueSize) {
	if (!GetConfig())
		return false;
	*valueSize = config.valueSize;
	return true;
}

// TODO: we should return more information about the status including time delays before the next retry
bool Weaver::WeaverVerify(const uint32_t slot, const void* weaver_key, std::vector<uint8_t>* payload) {
	bool callbackCalled = false;
	WeaverReadStatus status;
	std::vector<uint8_t> readValue;
	uint32_t timeout;
	uint32_t keySize;
	if (!GetKeySize(&keySize))
		return false;
	std::vector<uint8_t> key;
	key.resize(keySize);
	uint32_t index = 0;
	unsigned char* ptr = (unsigned char*)weaver_key;
	for (index = 0; index < keySize; index++) {
		key[index] = *ptr;
		ptr++;
	}
	const auto readRet = mDevice->read(slot, key, [&](WeaverReadStatus s, WeaverReadResponse r) {
		callbackCalled = true;
		status = s;
		readValue = r.value;
		timeout = r.timeout;
	});
	if (readRet.isOk() && callbackCalled && status == WeaverReadStatus::OK && timeout == 0) {
		*payload = readValue;
		return true;
	}
	return false;
}

}  // namespace vold
}  // namespace android
