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

// Error.h: Defines the egl::Error and gl::Error classes which encapsulate API errors
// and optional error messages.

#ifndef LIBANGLE_ERROR_H_
#define LIBANGLE_ERROR_H_

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "angle_gl.h"
#include "common/angleutils.h"
#include "common/debug.h"

#include <memory>
#include <ostream>
#include <string>

namespace angle
{
template <typename ErrorT, typename ErrorBaseT, ErrorBaseT NoErrorVal, typename CodeT, CodeT EnumT>
class ErrorStreamBase : angle::NonCopyable
{
  public:
    ErrorStreamBase() : mID(EnumT) {}
    ErrorStreamBase(GLuint id) : mID(id) {}

    template <typename T>
    ErrorStreamBase &operator<<(T value)
    {
        mErrorStream << value;
        return *this;
    }

    operator ErrorT() { return ErrorT(EnumT, mID, mErrorStream.str()); }

  private:
    GLuint mID;
    std::ostringstream mErrorStream;
};
}  // namespace angle

namespace egl
{
class Error;
}  // namespace egl

namespace egl
{

class ANGLE_NO_DISCARD Error final
{
  public:
    explicit inline Error(EGLint errorCode);
    Error(EGLint errorCode, std::string &&message);
    Error(EGLint errorCode, EGLint id, std::string &&message);
    inline Error(const Error &other);
    inline Error(Error &&other);
    inline ~Error() = default;

    inline Error &operator=(const Error &other);
    inline Error &operator=(Error &&other);

    inline EGLint getCode() const;
    inline EGLint getID() const;
    inline bool isError() const;

    const std::string &getMessage() const;

    static inline Error NoError();

  private:
    void createMessageString() const;

    friend std::ostream &operator<<(std::ostream &os, const Error &err);

    EGLint mCode;
    EGLint mID;
    mutable std::unique_ptr<std::string> mMessage;
};

namespace priv
{

template <EGLint EnumT>
using ErrorStream = angle::ErrorStreamBase<Error, EGLint, EGL_SUCCESS, EGLint, EnumT>;

}  // namespace priv

using EglBadAccess         = priv::ErrorStream<EGL_BAD_ACCESS>;
using EglBadAlloc          = priv::ErrorStream<EGL_BAD_ALLOC>;
using EglBadAttribute      = priv::ErrorStream<EGL_BAD_ATTRIBUTE>;
using EglBadConfig         = priv::ErrorStream<EGL_BAD_CONFIG>;
using EglBadContext        = priv::ErrorStream<EGL_BAD_CONTEXT>;
using EglBadCurrentSurface = priv::ErrorStream<EGL_BAD_CURRENT_SURFACE>;
using EglBadDevice         = priv::ErrorStream<EGL_BAD_DEVICE_EXT>;
using EglBadDisplay        = priv::ErrorStream<EGL_BAD_DISPLAY>;
using EglBadMatch          = priv::ErrorStream<EGL_BAD_MATCH>;
using EglBadNativeWindow   = priv::ErrorStream<EGL_BAD_NATIVE_WINDOW>;
using EglBadNativePixmap   = priv::ErrorStream<EGL_BAD_NATIVE_PIXMAP>;
using EglBadParameter      = priv::ErrorStream<EGL_BAD_PARAMETER>;
using EglBadState          = priv::ErrorStream<EGL_BAD_STATE_KHR>;
using EglBadStream         = priv::ErrorStream<EGL_BAD_STREAM_KHR>;
using EglBadSurface        = priv::ErrorStream<EGL_BAD_SURFACE>;
using EglContextLost       = priv::ErrorStream<EGL_CONTEXT_LOST>;
using EglNotInitialized    = priv::ErrorStream<EGL_NOT_INITIALIZED>;

inline Error NoError()
{
    return Error::NoError();
}

}  // namespace egl

#define ANGLE_CONCAT1(x, y) x##y
#define ANGLE_CONCAT2(x, y) ANGLE_CONCAT1(x, y)
#define ANGLE_LOCAL_VAR ANGLE_CONCAT2(_localVar, __LINE__)

#define ANGLE_TRY_TEMPLATE(EXPR, FUNC)                \
    do                                                \
    {                                                 \
        auto ANGLE_LOCAL_VAR = EXPR;                  \
        if (ANGLE_UNLIKELY(IsError(ANGLE_LOCAL_VAR))) \
        {                                             \
            FUNC(ANGLE_LOCAL_VAR);                    \
        }                                             \
    } while (0)

#define ANGLE_RETURN(X) return X;
#define ANGLE_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_RETURN)

// TODO(jmadill): Remove after EGL error refactor. http://anglebug.com/3041
#define ANGLE_SWALLOW_ERR(EXPR)                                       \
    do                                                                \
    {                                                                 \
        auto ANGLE_LOCAL_VAR = EXPR;                                  \
        if (ANGLE_UNLIKELY(IsError(ANGLE_LOCAL_VAR)))                 \
        {                                                             \
            ERR() << "Unhandled internal error: " << ANGLE_LOCAL_VAR; \
        }                                                             \
    } while (0)

#undef ANGLE_LOCAL_VAR
#undef ANGLE_CONCAT2
#undef ANGLE_CONCAT1

#define ANGLE_CHECK(CONTEXT, EXPR, MESSAGE, ERROR)                                    \
    do                                                                                \
    {                                                                                 \
        if (ANGLE_UNLIKELY(!(EXPR)))                                                  \
        {                                                                             \
            CONTEXT->handleError(ERROR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \
            return angle::Result::Stop;                                               \
        }                                                                             \
    } while (0)

namespace angle
{
// Result signals if calling code should continue running or early exit. A value of Stop can
// either indicate an Error or a non-Error early exit condition such as a detected no-op.
// Incomplete signals special cases that are neither success nor failure but require
// special attention.
enum class ANGLE_NO_DISCARD Result
{
    Continue,
    Stop,
    Incomplete,
};

// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
egl::Error ResultToEGL(Result result);
}  // namespace angle

// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
inline bool IsError(angle::Result result)
{
    return result == angle::Result::Stop;
}

// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
inline bool IsError(const egl::Error &err)
{
    return err.isError();
}

// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
inline bool IsError(bool value)
{
    return !value;
}

// Utility macro for handling implementation methods inside Validation.
#define ANGLE_HANDLE_VALIDATION_ERR(X) \
    do                                 \
    {                                  \
        (void)(X);                     \
        return false;                  \
    } while (0)

#define ANGLE_VALIDATION_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_VALIDATION_ERR)

#include "Error.inc"

#endif  // LIBANGLE_ERROR_H_
