// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// 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.

#ifndef VK_DEBUG_VARIABLE_HPP_
#define VK_DEBUG_VARIABLE_HPP_

#include "ID.hpp"
#include "Type.hpp"
#include "Value.hpp"

#include "marl/mutex.h"
#include "marl/tsa.h"

#include <algorithm>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

namespace vk {
namespace dbg {

// Variable is a named value.
struct Variable
{
	std::string name;
	std::shared_ptr<Value> value;
};

// VariableContainer is a collection of named values.
class VariableContainer : public Value
{
public:
	using ID = dbg::ID<VariableContainer>;

	inline VariableContainer(ID id);

	// foreach() calls cb with each of the variables in the container.
	// F must be a function with the signature void(const Variable&).
	template<typename F>
	inline void foreach(size_t startIndex, size_t count, const F &cb) const;

	// find() looks up the variable with the given name.
	// If the variable with the given name is found, cb is called with the
	// variable and find() returns true.
	template<typename F>
	inline bool find(const std::string &name, const F &cb) const;

	// put() places the variable var into the container.
	inline void put(const Variable &var);

	// put() places the variable with the given name and value into the container.
	inline void put(const std::string &name, const std::shared_ptr<Value> &value);

	// extend() adds base to the list of VariableContainers that will be
	// searched and traversed for variables.
	inline void extend(const std::shared_ptr<VariableContainer> &base);

	// The unique identifier of the variable.
	const ID id;

private:
	struct ForeachIndex
	{
		size_t start;
		size_t count;
	};

	template<typename F>
	inline void foreach(ForeachIndex &index, const F &cb) const;

	inline std::shared_ptr<Type> type() const override;
	inline const void *get() const override;

	mutable marl::mutex mutex;
	std::vector<Variable> variables GUARDED_BY(mutex);
	std::unordered_map<std::string, int> indices GUARDED_BY(mutex);
	std::vector<std::shared_ptr<VariableContainer>> extends GUARDED_BY(mutex);
};

VariableContainer::VariableContainer(ID id)
    : id(id)
{}

template<typename F>
void VariableContainer::foreach(size_t startIndex, size_t count, const F &cb) const
{
	auto index = ForeachIndex{ startIndex, count };
	foreach(index, cb);
}

template<typename F>
void VariableContainer::foreach(ForeachIndex &index, const F &cb) const
{
	marl::lock lock(mutex);
	for(size_t i = index.start; i < variables.size() && i < index.count; i++)
	{
		cb(variables[i]);
	}

	index.start -= std::min(index.start, variables.size());
	index.count -= std::min(index.count, variables.size());

	for(auto &base : extends)
	{
		base->foreach(index, cb);
	}
}

template<typename F>
bool VariableContainer::find(const std::string &name, const F &cb) const
{
	marl::lock lock(mutex);
	for(auto const &var : variables)
	{
		if(var.name == name)
		{
			cb(var);
			return true;
		}
	}
	for(auto &base : extends)
	{
		if(base->find(name, cb))
		{
			return true;
		}
	}
	return false;
}

void VariableContainer::put(const Variable &var)
{
	marl::lock lock(mutex);
	auto it = indices.find(var.name);
	if(it == indices.end())
	{
		indices.emplace(var.name, variables.size());
		variables.push_back(var);
	}
	else
	{
		variables[it->second].value = var.value;
	}
}

void VariableContainer::put(const std::string &name,
                            const std::shared_ptr<Value> &value)
{
	put({ name, value });
}

void VariableContainer::extend(const std::shared_ptr<VariableContainer> &base)
{
	marl::lock lock(mutex);
	extends.emplace_back(base);
}

std::shared_ptr<Type> VariableContainer::type() const
{
	return TypeOf<VariableContainer>::get();
}

const void *VariableContainer::get() const
{
	return nullptr;
}

}  // namespace dbg
}  // namespace vk

#endif  // VK_DEBUG_VARIABLE_HPP_