// Copyright 2016 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 "DirectiveHandler.h"

#include <sstream>

#include "debug.h"
#include "Diagnostics.h"

static TBehavior getBehavior(const std::string& str)
{
	static const char kRequire[] = "require";
	static const char kEnable[] = "enable";
	static const char kDisable[] = "disable";
	static const char kWarn[] = "warn";

	if (str == kRequire) return EBhRequire;
	else if (str == kEnable) return EBhEnable;
	else if (str == kDisable) return EBhDisable;
	else if (str == kWarn) return EBhWarn;
	return EBhUndefined;
}

TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
                                     TDiagnostics& diagnostics,
                                     int& shaderVersion)
	: mExtensionBehavior(extBehavior),
	  mDiagnostics(diagnostics),
	  mShaderVersion(shaderVersion)
{
}

TDirectiveHandler::~TDirectiveHandler()
{
}

void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
                                    const std::string& msg)
{
	mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
}

void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
                                     const std::string& name,
                                     const std::string& value,
                                     bool stdgl)
{
	static const char kSTDGL[] = "STDGL";
	static const char kOptimize[] = "optimize";
	static const char kDebug[] = "debug";
	static const char kOn[] = "on";
	static const char kOff[] = "off";

	bool invalidValue = false;
	if (stdgl || (name == kSTDGL))
	{
		// The STDGL pragma is used to reserve pragmas for use by future
		// revisions of GLSL. Ignore it.
		return;
	}
	else if (name == kOptimize)
	{
		if (value == kOn) mPragma.optimize = true;
		else if (value == kOff) mPragma.optimize = false;
		else invalidValue = true;
	}
	else if (name == kDebug)
	{
		if (value == kOn) mPragma.debug = true;
		else if (value == kOff) mPragma.debug = false;
		else invalidValue = true;
	}
	else
	{
		mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
		return;
	}

	if (invalidValue)
		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
		                       "invalid pragma value", value,
		                       "'on' or 'off' expected");
}

void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
                                        const std::string& name,
                                        const std::string& behavior)
{
	static const char kExtAll[] = "all";

	TBehavior behaviorVal = getBehavior(behavior);
	if (behaviorVal == EBhUndefined)
	{
		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
		                       "behavior", name, "invalid");
		return;
	}

	if (name == kExtAll)
	{
		if (behaviorVal == EBhRequire)
		{
			mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
			                       "extension", name,
			                       "cannot have 'require' behavior");
		}
		else if (behaviorVal == EBhEnable)
		{
			mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
			                       "extension", name,
			                       "cannot have 'enable' behavior");
		}
		else
		{
			for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
				 iter != mExtensionBehavior.end(); ++iter)
				iter->second = behaviorVal;
		}
		return;
	}

	TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
	if (iter != mExtensionBehavior.end())
	{
		iter->second = behaviorVal;
		return;
	}

	pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
	switch (behaviorVal) {
	case EBhRequire:
		severity = pp::Diagnostics::PP_ERROR;
		break;
	case EBhEnable:
	case EBhWarn:
	case EBhDisable:
		severity = pp::Diagnostics::PP_WARNING;
		break;
	default:
		UNREACHABLE(behaviorVal);
		break;
	}
	mDiagnostics.writeInfo(severity, loc,
	                       "extension", name, "is not supported");
}

void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
                                      int version)
{
	if (version == 100 ||
	    version == 300)
	{
		mShaderVersion = version;
	}
	else
	{
		std::stringstream stream;
		stream << version;
		std::string str = stream.str();
		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
		                       "version number", str, "not supported");
	}
}
