// Copyright (c) 2015-2016 The Khronos Group Inc.
//
// 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 "source/diagnostic.h"

#include <cassert>
#include <cstring>
#include <iostream>
#include <sstream>
#include <utility>

#include "source/table.h"

// Diagnostic API

spv_diagnostic spvDiagnosticCreate(const spv_position position,
                                   const char* message) {
  spv_diagnostic diagnostic = new spv_diagnostic_t;
  if (!diagnostic) return nullptr;
  size_t length = strlen(message) + 1;
  diagnostic->error = new char[length];
  if (!diagnostic->error) {
    delete diagnostic;
    return nullptr;
  }
  diagnostic->position = *position;
  diagnostic->isTextSource = false;
  memset(diagnostic->error, 0, length);
  strcpy(diagnostic->error, message);
  return diagnostic;
}

void spvDiagnosticDestroy(spv_diagnostic diagnostic) {
  if (!diagnostic) return;
  delete[] diagnostic->error;
  delete diagnostic;
}

spv_result_t spvDiagnosticPrint(const spv_diagnostic diagnostic) {
  if (!diagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;

  if (diagnostic->isTextSource) {
    // NOTE: This is a text position
    // NOTE: add 1 to the line as editors start at line 1, we are counting new
    // line characters to start at line 0
    std::cerr << "error: " << diagnostic->position.line + 1 << ": "
              << diagnostic->position.column + 1 << ": " << diagnostic->error
              << "\n";
    return SPV_SUCCESS;
  }

  // NOTE: Assume this is a binary position
  std::cerr << "error: ";
  if (diagnostic->position.index > 0)
    std::cerr << diagnostic->position.index << ": ";
  std::cerr << diagnostic->error << "\n";
  return SPV_SUCCESS;
}

namespace spvtools {

DiagnosticStream::DiagnosticStream(DiagnosticStream&& other)
    : stream_(),
      position_(other.position_),
      consumer_(other.consumer_),
      disassembled_instruction_(std::move(other.disassembled_instruction_)),
      error_(other.error_) {
  // Prevent the other object from emitting output during destruction.
  other.error_ = SPV_FAILED_MATCH;
  // Some platforms are missing support for std::ostringstream functionality,
  // including:  move constructor, swap method.  Either would have been a
  // better choice than copying the string.
  stream_ << other.stream_.str();
}

DiagnosticStream::~DiagnosticStream() {
  if (error_ != SPV_FAILED_MATCH && consumer_ != nullptr) {
    auto level = SPV_MSG_ERROR;
    switch (error_) {
      case SPV_SUCCESS:
      case SPV_REQUESTED_TERMINATION:  // Essentially success.
        level = SPV_MSG_INFO;
        break;
      case SPV_WARNING:
        level = SPV_MSG_WARNING;
        break;
      case SPV_UNSUPPORTED:
      case SPV_ERROR_INTERNAL:
      case SPV_ERROR_INVALID_TABLE:
        level = SPV_MSG_INTERNAL_ERROR;
        break;
      case SPV_ERROR_OUT_OF_MEMORY:
        level = SPV_MSG_FATAL;
        break;
      default:
        break;
    }
    if (!disassembled_instruction_.empty())
      stream_ << std::endl << "  " << disassembled_instruction_ << std::endl;

    if (!shader_debug_info_.empty()) stream_ << shader_debug_info_;

    consumer_(level, "input", position_, stream_.str().c_str());
  }
}

void UseDiagnosticAsMessageConsumer(spv_context context,
                                    spv_diagnostic* diagnostic) {
  assert(diagnostic && *diagnostic == nullptr);

  auto create_diagnostic = [diagnostic](spv_message_level_t, const char*,
                                        const spv_position_t& position,
                                        const char* message) {
    auto p = position;
    spvDiagnosticDestroy(*diagnostic);  // Avoid memory leak.
    *diagnostic = spvDiagnosticCreate(&p, message);
  };
  SetContextMessageConsumer(context, std::move(create_diagnostic));
}

std::string spvResultToString(spv_result_t res) {
  std::string out;
  switch (res) {
    case SPV_SUCCESS:
      out = "SPV_SUCCESS";
      break;
    case SPV_UNSUPPORTED:
      out = "SPV_UNSUPPORTED";
      break;
    case SPV_END_OF_STREAM:
      out = "SPV_END_OF_STREAM";
      break;
    case SPV_WARNING:
      out = "SPV_WARNING";
      break;
    case SPV_FAILED_MATCH:
      out = "SPV_FAILED_MATCH";
      break;
    case SPV_REQUESTED_TERMINATION:
      out = "SPV_REQUESTED_TERMINATION";
      break;
    case SPV_ERROR_INTERNAL:
      out = "SPV_ERROR_INTERNAL";
      break;
    case SPV_ERROR_OUT_OF_MEMORY:
      out = "SPV_ERROR_OUT_OF_MEMORY";
      break;
    case SPV_ERROR_INVALID_POINTER:
      out = "SPV_ERROR_INVALID_POINTER";
      break;
    case SPV_ERROR_INVALID_BINARY:
      out = "SPV_ERROR_INVALID_BINARY";
      break;
    case SPV_ERROR_INVALID_TEXT:
      out = "SPV_ERROR_INVALID_TEXT";
      break;
    case SPV_ERROR_INVALID_TABLE:
      out = "SPV_ERROR_INVALID_TABLE";
      break;
    case SPV_ERROR_INVALID_VALUE:
      out = "SPV_ERROR_INVALID_VALUE";
      break;
    case SPV_ERROR_INVALID_DIAGNOSTIC:
      out = "SPV_ERROR_INVALID_DIAGNOSTIC";
      break;
    case SPV_ERROR_INVALID_LOOKUP:
      out = "SPV_ERROR_INVALID_LOOKUP";
      break;
    case SPV_ERROR_INVALID_ID:
      out = "SPV_ERROR_INVALID_ID";
      break;
    case SPV_ERROR_INVALID_CFG:
      out = "SPV_ERROR_INVALID_CFG";
      break;
    case SPV_ERROR_INVALID_LAYOUT:
      out = "SPV_ERROR_INVALID_LAYOUT";
      break;
    default:
      out = "Unknown Error";
  }
  return out;
}

}  // namespace spvtools
