//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include "DirectiveHandler.h"

#include <sstream>

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

static TBehavior getBehavior(const std::string& str)
{
    static const std::string kRequire("require");
    static const std::string kEnable("enable");
    static const std::string kDisable("disable");
    static const std::string 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)
{
    static const std::string kSTDGL("STDGL");
    static const std::string kOptimize("optimize");
    static const std::string kDebug("debug");
    static const std::string kOn("on");
    static const std::string kOff("off");

    bool invalidValue = false;
    if (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::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 std::string 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();
        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");
    }
}
