// 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 <cassert>
#include <cstdint>
#include <memory>

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.OES_EGL_image_external_essl3 = 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.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();

	auto routine = program("VertexRoutine");
	assert(routine);
	const void *entry = routine->getEntry();
	assert(entry);
	(void)entry;

	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
