// Copyright 2017 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.

#include "OpenGL/compiler/InitializeGlobals.h"
#include "OpenGL/compiler/InitializeParseContext.h"
#include "OpenGL/compiler/TranslatorASM.h"

// TODO: Debug macros of the GLSL compiler clash with core SwiftShader's.
// They should not be exposed through the interface headers above.
#undef ASSERT
#undef UNIMPLEMENTED

#include "Renderer/VertexProcessor.hpp"
#include "Shader/VertexProgram.hpp"

#include <cstdint>
#include <memory>
#include <cassert>

namespace {

// TODO(cwallez@google.com): Like in ANGLE, disable most of the pool allocator for fuzzing
// This is a helper class to make sure all the resources used by the compiler are initialized
class ScopedPoolAllocatorAndTLS {
	public:
		ScopedPoolAllocatorAndTLS() {
			InitializeParseContextIndex();
			InitializePoolIndex();
			SetGlobalPoolAllocator(&allocator);
		}
		~ScopedPoolAllocatorAndTLS() {
			SetGlobalPoolAllocator(nullptr);
			FreePoolIndex();
			FreeParseContextIndex();
		}

	private:
		TPoolAllocator allocator;
};

// Trivial implementation of the glsl::Shader interface that fakes being an API-level
// shader object.
class FakeVS : public glsl::Shader {
	public:
		FakeVS(sw::VertexShader* bytecode) : bytecode(bytecode) {
		}

		sw::Shader *getShader() const override {
			return bytecode;
		}
		sw::VertexShader *getVertexShader() const override {
			return bytecode;
		}

	private:
		sw::VertexShader* bytecode;
};

} // anonymous namespace

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
	// Data layout:
	//
	// byte: boolean states
	// {
	//   byte: stream type
	//   byte: stream count and normalized
	// } [MAX_VERTEX_INPUTS]
	// {
	//   byte[32]: reserved sampler state
	// } [VERTEX_TEXTURE_IMAGE_UNITS]
	//
	// char source[] // null terminated
	const size_t kHeaderSize = 1 + 2 * sw::MAX_VERTEX_INPUTS + 32 * sw::VERTEX_TEXTURE_IMAGE_UNITS;

	if(size <= kHeaderSize)
	{
		return 0;
	}

	if(data[size - 1] != 0)
	{
		return 0;
	}

	std::unique_ptr<ScopedPoolAllocatorAndTLS> allocatorAndTLS(new ScopedPoolAllocatorAndTLS);
	std::unique_ptr<sw::VertexShader> shader(new sw::VertexShader);
	std::unique_ptr<FakeVS> fakeVS(new FakeVS(shader.get()));
	
	std::unique_ptr<TranslatorASM> glslCompiler(new TranslatorASM(fakeVS.get(), GL_VERTEX_SHADER));

	// TODO(cwallez@google.com): have a function to init to default values somewhere
	ShBuiltInResources resources;
	resources.MaxVertexAttribs = sw::MAX_VERTEX_INPUTS;
	resources.MaxVertexUniformVectors = sw::VERTEX_UNIFORM_VECTORS - 3;
	resources.MaxVaryingVectors = MIN(sw::MAX_VERTEX_OUTPUTS, sw::MAX_VERTEX_INPUTS);
	resources.MaxVertexTextureImageUnits = sw::VERTEX_TEXTURE_IMAGE_UNITS;
	resources.MaxCombinedTextureImageUnits = sw::TEXTURE_IMAGE_UNITS + sw::VERTEX_TEXTURE_IMAGE_UNITS;
	resources.MaxTextureImageUnits = sw::TEXTURE_IMAGE_UNITS;
	resources.MaxFragmentUniformVectors = sw::FRAGMENT_UNIFORM_VECTORS - 3;
	resources.MaxDrawBuffers = sw::RENDERTARGETS;
	resources.MaxVertexOutputVectors = 16; // ???
	resources.MaxFragmentInputVectors = 15; // ???
	resources.MinProgramTexelOffset = sw::MIN_PROGRAM_TEXEL_OFFSET;
	resources.MaxProgramTexelOffset = sw::MAX_PROGRAM_TEXEL_OFFSET;
	resources.OES_standard_derivatives = 1;
	resources.OES_fragment_precision_high = 1;
	resources.OES_EGL_image_external = 1;
	resources.EXT_draw_buffers = 1;
	resources.ARB_texture_rectangle = 1;
	resources.MaxCallStackDepth = 16;

	glslCompiler->Init(resources);

	const char* glslSource = reinterpret_cast<const char*>(data + kHeaderSize);
	if (!glslCompiler->compile(&glslSource, 1, SH_OBJECT_CODE))
	{
		return 0;
	}

	std::unique_ptr<sw::VertexShader> bytecodeShader(new sw::VertexShader(fakeVS->getVertexShader()));

	sw::VertexProcessor::State state;

	state.textureSampling = bytecodeShader->containsTextureSampling();
	state.positionRegister = bytecodeShader->getPositionRegister();
	state.pointSizeRegister = bytecodeShader->getPointSizeRegister();

	state.preTransformed = (data[0] & 0x01) != 0;
	state.superSampling = (data[0] & 0x02) != 0;
	state.multiSampling = (data[0] & 0x04) != 0;

	state.transformFeedbackQueryEnabled = (data[0] & 0x08) != 0;
	state.transformFeedbackEnabled = (data[0] & 0x10) != 0;
	state.verticesPerPrimitive = 1 + ((data[0] & 0x20) != 0) + ((data[0] & 0x40) != 0);

	if((data[0] & 0x80) != 0)   // Unused/reserved.
	{
		return 0;
	}

	constexpr int MAX_ATTRIBUTE_COMPONENTS = 4;

	struct Stream
	{
		uint8_t count : BITS(MAX_ATTRIBUTE_COMPONENTS);
		bool normalized : 1;
		uint8_t reserved : 8 - BITS(MAX_ATTRIBUTE_COMPONENTS) - 1;
	};

	for(int i = 0; i < sw::MAX_VERTEX_INPUTS; i++)
	{
		sw::StreamType type = (sw::StreamType)data[1 + 2 * i + 0];
		Stream stream = (Stream&)data[1 + 2 * i + 1];

		if(type > sw::STREAMTYPE_LAST) return 0;
		if(stream.count > MAX_ATTRIBUTE_COMPONENTS) return 0;
		if(stream.reserved != 0) return 0;

		state.input[i].type = type;
		state.input[i].count = stream.count;
		state.input[i].normalized = stream.normalized;
		state.input[i].attribType = bytecodeShader->getAttribType(i);
	}

	for(unsigned int i = 0; i < sw::VERTEX_TEXTURE_IMAGE_UNITS; i++)
	{
		// TODO
	//	if(bytecodeShader->usesSampler(i))
	//	{
	//		state.samplerState[i] = context->sampler[sw::TEXTURE_IMAGE_UNITS + i].samplerState();
	//	}

		for(int j = 0; j < 32; j++)
		{
			if(data[1 + 2 * sw::MAX_VERTEX_INPUTS + 32 * i + j] != 0)
			{
				return 0;
			}
		}
	}

	for(int i = 0; i < sw::MAX_VERTEX_OUTPUTS; i++)
	{
		state.output[i].xWrite = bytecodeShader->getOutput(i, 0).active();
		state.output[i].yWrite = bytecodeShader->getOutput(i, 1).active();
		state.output[i].zWrite = bytecodeShader->getOutput(i, 2).active();
		state.output[i].wWrite = bytecodeShader->getOutput(i, 3).active();
	}

	sw::VertexProgram program(state, bytecodeShader.get());
	program.generate();

	sw::Routine *routine = program("VertexRoutine");
	assert(routine);
	const void *entry = routine->getEntry();
	assert(entry); (void)entry;
	delete routine;

	return 0;
}

#if defined(FUZZER_STANDALONE_REPRODUCE)
int main(int argc, char *argv[])
{
	FILE *file = fopen("clusterfuzz-testcase", "r");

	fseek(file, 0L, SEEK_END);
	long numbytes = ftell(file);
	fseek(file, 0L, SEEK_SET);
	uint8_t *buffer = (uint8_t*)calloc(numbytes, sizeof(uint8_t));
	fread(buffer, sizeof(char), numbytes, file);
	fclose(file);

	while(true)
	{
		LLVMFuzzerTestOneInput(buffer, numbytes);
	}

	free(buffer);

	return 0;
}
#endif