// Copyright 2020 The Fuchsia 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 "src/lib/fidl_codec/semantic_parser.h"

#include <lib/syslog/cpp/macros.h>

#include <cctype>
#include <iostream>
#include <memory>
#include <ostream>
#include <string>

#include "src/lib/fidl_codec/library_loader.h"
#include "src/lib/fidl_codec/wire_types.h"

namespace fidl_codec {
namespace semantic {

std::ostream& ParserErrors::AddError() {
  ++error_count_;
  return os_;
}

std::ostream& ParserErrors::AddError(const Location& location) {
  ++error_count_;
  // Computes the line and column in the buffer of the error.
  std::string_view::const_iterator start_line = location.buffer().begin();
  int line = 1;
  int column = 1;
  std::string_view::const_iterator current = start_line;
  while (current != location.location()) {
    if (*current == '\n') {
      start_line = ++current;
      ++line;
      column = 1;
    } else {
      ++current;
      ++column;
    }
  }
  while (current != location.buffer().end()) {
    if (*current == '\n') {
      break;
    }
    ++current;
  }
  // Displays the line of the error (the whole line).
  os_ << std::string_view(&*start_line, current - start_line) << '\n';
  // Displays some spaces. This way, the caret will be right under the error location.
  // It will point the first character of the previous line where the error is.
  current = start_line;
  for (int i = 1; i < column; ++i) {
    os_ << ((*current == '\t') ? '\t' : ' ');
    ++current;
  }
  // Displays the marker (caret) which points to the error, the line and the column.
  os_ << "^\n" << line << ":" << column << ": ";
  // Returns the stream. This way, the caller can add the error message.
  return os_;
}

void SemanticParser::NextLexicalToken() {
  bool error_found = false;
  for (;;) {
    while (isspace(*next_)) {
      ++next_;
    }
    current_location_ = next_;
    switch (*next_) {
      case '\0':
        current_lexical_token_ = LexicalToken::kEof;
        return;
      case '\'':
        LexerString();
        return;
      case '{':
        ++next_;
        current_lexical_token_ = LexicalToken::kLeftBrace;
        return;
      case '}':
        ++next_;
        current_lexical_token_ = LexicalToken::kRightBrace;
        return;
      case '(':
        ++next_;
        current_lexical_token_ = LexicalToken::kLeftParenthesis;
        return;
      case ')':
        ++next_;
        current_lexical_token_ = LexicalToken::kRightParenthesis;
        return;
      case ':':
        ++next_;
        if (*next_ == ':') {
          ++next_;
          current_lexical_token_ = LexicalToken::kColonColon;
        } else {
          current_lexical_token_ = LexicalToken::kColon;
        }
        return;
      case ',':
        ++next_;
        current_lexical_token_ = LexicalToken::kComma;
        return;
      case '.':
        ++next_;
        current_lexical_token_ = LexicalToken::kDot;
        return;
      case '=':
        ++next_;
        current_lexical_token_ = LexicalToken::kEqual;
        return;
      case ';':
        ++next_;
        current_lexical_token_ = LexicalToken::kSemicolon;
        return;
      case '/':
        ++next_;
        current_lexical_token_ = LexicalToken::kSlash;
        return;
      default:
        if (isalpha(*next_) || (*next_ == '_')) {
          LexerIdentifier();
          return;
        }
        if (!error_found && !ignore_unknown_characters_) {
          error_found = true;
          AddError() << "Unknown character <" << *next_ << ">\n";
        }
        ++next_;
        break;
    }
  }
}

void SemanticParser::JumpToSemicolon() {
  IgnoreUnknownCharacters ignore_unknown_characters(this);
  while (!IsEof()) {
    if (IsSemicolon() || IsRightBrace()) {
      return;
    }
    if (ConsumeLeftParenthesis()) {
      SkipRightParenthesis();
    } else {
      NextLexicalToken();
    }
  }
}

void SemanticParser::SkipSemicolon() {
  IgnoreUnknownCharacters ignore_unknown_characters(this);
  while (!IsEof()) {
    if (ConsumeSemicolon() || IsRightBrace()) {
      return;
    }
    if (ConsumeLeftParenthesis()) {
      SkipRightParenthesis();
    } else {
      NextLexicalToken();
    }
  }
}

void SemanticParser::SkipBlock() {
  IgnoreUnknownCharacters ignore_unknown_characters(this);
  while (!IsEof()) {
    if (ConsumeRightBrace() || ConsumeSemicolon()) {
      return;
    }
    if (ConsumeLeftBrace()) {
      SkipRightBrace();
    } else {
      NextLexicalToken();
    }
  }
}

void SemanticParser::SkipRightBrace() {
  IgnoreUnknownCharacters ignore_unknown_characters(this);
  while (!IsEof()) {
    if (ConsumeRightBrace()) {
      return;
    }
    if (ConsumeLeftBrace()) {
      SkipRightBrace();
    } else {
      NextLexicalToken();
    }
  }
}

void SemanticParser::SkipRightParenthesis() {
  IgnoreUnknownCharacters ignore_unknown_characters(this);
  while (!IsEof()) {
    if (ConsumeRightParenthesis() || IsSemicolon()) {
      return;
    }
    if (ConsumeLeftBrace()) {
      SkipRightBrace();
    } else if (ConsumeLeftParenthesis()) {
      SkipRightParenthesis();
    } else {
      NextLexicalToken();
    }
  }
}

std::string SemanticParser::ConsumeString() {
  std::string result = std::string(current_string_);
  size_t pos = 0;
  for (;;) {
    auto backslash = result.find('\\', pos);
    if (backslash == std::string::npos) {
      NextLexicalToken();
      return result;
    }
    // We already checked that backslashes are followed by another character.
    FX_DCHECK(backslash < result.size() - 1);
    result.erase(backslash);
    pos = backslash + 1;
  }
}

void SemanticParser::ParseSemantic() {
  while (!IsEof()) {
    if (Is("library")) {
      ParseLibrary();
    } else {
      AddError() << "Keyword 'library' expected.\n";
      SkipBlock();
    }
  }
}

void SemanticParser::ParseLibrary() {
  allow_dots_in_identifiers_ = true;
  NextLexicalToken();
  if (!IsIdentifier()) {
    AddError() << "Library name expected.\n";
    SkipBlock();
    return;
  }
  allow_dots_in_identifiers_ = false;
  Library* library = library_loader_->GetLibraryFromName(std::string(current_string_));
  if (library == nullptr) {
    AddError() << "Library " << current_string_ << " not found.\n";
  } else {
    library->DecodeTypes();
  }
  NextLexicalToken();
  if (!ParseLeftBrace()) {
    SkipBlock();
    return;
  }
  while (!ConsumeRightBrace()) {
    if (!IsIdentifier()) {
      AddError() << "Protocol name expected.\n";
      SkipBlock();
      NextLexicalToken();
      return;
    }
    Protocol* protocol = nullptr;
    if (library != nullptr) {
      std::string protocol_name = library->name() + "/" + std::string(current_string_);
      if (!library->GetProtocolByName(protocol_name, &protocol)) {
        AddError() << "Protocol " << current_string_ << " not found in library " << library->name()
                   << '\n';
      }
    }
    NextLexicalToken();
    if (!ParseColonColon()) {
      SkipBlock();
      NextLexicalToken();
      return;
    }
    if (!IsIdentifier()) {
      AddError() << "Method name expected.\n";
      SkipBlock();
      NextLexicalToken();
      return;
    }
    ProtocolMethod* method = nullptr;
    if (protocol != nullptr) {
      method = protocol->GetMethodByName(current_string_);
      if (method == nullptr) {
        AddError() << "Method " << current_string_ << " not found in protocol " << protocol->name()
                   << '\n';
      }
    }
    NextLexicalToken();
    if (!ParseLeftBrace()) {
      SkipBlock();
      NextLexicalToken();
      return;
    }
    ParseMethod(method);
  }
}

void SemanticParser::ParseMethod(ProtocolMethod* method) {
  while (!ConsumeRightBrace() && !IsEof()) {
    if (Is("input_field")) {
      NextLexicalToken();
      ParseColon();
      std::unique_ptr<DisplayExpression> expression = ParseDisplayExpression();
      if (method != nullptr) {
        MethodDisplay* display = method->short_display();
        if (display == nullptr) {
          method->set_short_display(std::make_unique<MethodDisplay>());
          display = method->short_display();
        }
        display->AddInput(std::move(expression));
      }
      if (!ParseSemicolon()) {
        SkipSemicolon();
      }
    } else if (Is("result")) {
      NextLexicalToken();
      ParseColon();
      std::unique_ptr<DisplayExpression> expression = ParseDisplayExpression();
      if (method != nullptr) {
        MethodDisplay* display = method->short_display();
        if (display == nullptr) {
          method->set_short_display(std::make_unique<MethodDisplay>());
          display = method->short_display();
        }
        display->AddResult(std::move(expression));
      }
      if (!ParseSemicolon()) {
        SkipSemicolon();
      }
    } else {
      MethodSemantic* method_semantic = nullptr;
      if (method != nullptr) {
        method_semantic = method->semantic();
        if (method_semantic == nullptr) {
          method->set_semantic(std::make_unique<MethodSemantic>());
          method_semantic = method->semantic();
        }
      }
      ParseAssignment(method_semantic);
    }
  }
}

std::unique_ptr<DisplayExpression> SemanticParser::ParseDisplayExpression() {
  auto display_expression = std::make_unique<DisplayExpression>();
  if (IsString()) {
    display_expression->set_header(ConsumeString());
  }
  std::unique_ptr<Expression> expression = ParseExpression();
  if (expression != nullptr) {
    display_expression->set_expression(std::move(expression));
  }
  if (IsString()) {
    display_expression->set_footer(ConsumeString());
  }
  return display_expression;
}

void SemanticParser::ParseAssignment(MethodSemantic* method_semantic) {
  std::unique_ptr<Expression> destination = ParseExpression();
  if (destination == nullptr) {
    AddError() << "Assignment expected.\n";
    SkipSemicolon();
    return;
  }
  if (!ParseEqual()) {
    SkipSemicolon();
    return;
  }
  std::unique_ptr<Expression> source = ParseExpression();
  if (source == nullptr) {
    AddError() << "Expression expected.\n";
    SkipSemicolon();
    return;
  }
  if (method_semantic != nullptr) {
    method_semantic->AddAssignment(std::move(destination), std::move(source));
  }
  if (!ParseSemicolon()) {
    SkipSemicolon();
  }
}

std::unique_ptr<Expression> SemanticParser::ParseExpression() {
  return ParseMultiplicativeExpression();
}

std::unique_ptr<Expression> SemanticParser::ParseMultiplicativeExpression() {
  std::unique_ptr<Expression> expression = ParseAccessExpression();
  if (expression == nullptr) {
    return nullptr;
  }
  for (;;) {
    if (ConsumeSlash()) {
      std::unique_ptr<Expression> right = ParseAccessExpression();
      if (right == nullptr) {
        return nullptr;
      }
      expression = std::make_unique<ExpressionSlash>(std::move(expression), std::move(right));
    } else if (ConsumeColon()) {
      std::unique_ptr<Expression> right = ParseAccessExpression();
      if (right == nullptr) {
        return nullptr;
      }
      expression = std::make_unique<ExpressionColon>(std::move(expression), std::move(right));
    } else {
      return expression;
    }
  }
}

std::unique_ptr<Expression> SemanticParser::ParseAccessExpression() {
  std::unique_ptr<Expression> expression = ParseTerminalExpression();
  if (expression == nullptr) {
    return nullptr;
  }
  for (;;) {
    if (ConsumeDot()) {
      if (!IsIdentifier()) {
        AddError() << "Field name expected.\n";
        expression = std::make_unique<ExpressionFieldAccess>(std::move(expression), "");
      } else {
        std::string_view name = current_string_;
        NextLexicalToken();
        expression = std::make_unique<ExpressionFieldAccess>(std::move(expression), name);
      }
    } else {
      return expression;
    }
  }
}

std::unique_ptr<Expression> SemanticParser::ParseTerminalExpression() {
  if (IsString()) {
    return std::make_unique<ExpressionStringLiteral>(ConsumeString());
  }
  if (Consume("request")) {
    return std::make_unique<ExpressionRequest>();
  }
  if (Consume("handle")) {
    return std::make_unique<ExpressionHandle>();
  }
  if (Consume("HandleDescription")) {
    return ParseHandleDescription();
  }
  return nullptr;
}

std::unique_ptr<Expression> SemanticParser::ParseHandleDescription() {
  if (!ParseLeftParenthesis()) {
    JumpToSemicolon();
    return std::make_unique<ExpressionHandleDescription>(nullptr, nullptr);
  }
  std::unique_ptr<Expression> type = ParseExpression();
  if (type == nullptr) {
    AddError() << "Expression expected (handle type)";
    SkipRightParenthesis();
    return std::make_unique<ExpressionHandleDescription>(nullptr, nullptr);
  }
  if (!ParseComma()) {
    SkipRightParenthesis();
    return std::make_unique<ExpressionHandleDescription>(std::move(type), nullptr);
  }
  std::unique_ptr<Expression> path = ParseExpression();
  if (path == nullptr) {
    AddError() << "Expression expected (handle path)";
    SkipRightParenthesis();
    return std::make_unique<ExpressionHandleDescription>(std::move(type), nullptr);
  }
  if (!ParseRightParenthesis()) {
    SkipRightParenthesis();
  }
  return std::make_unique<ExpressionHandleDescription>(std::move(type), std::move(path));
}

void SemanticParser::LexerIdentifier() {
  std::string_view::const_iterator start = next_;
  while (isalnum(*next_) || (*next_ == '_') || ((*next_ == '.') && allow_dots_in_identifiers_)) {
    ++next_;
  }
  current_string_ = std::string_view(&*start, next_ - start);
  current_lexical_token_ = LexicalToken::kIdentifier;
}

void SemanticParser::LexerString() {
  std::string_view::const_iterator start = ++next_;
  while (*next_ != '\'') {
    if (*next_ == '\0') {
      AddError() << "Unterminated string.\n";
      current_lexical_token_ = LexicalToken::kString;
      next_ = start;
      current_string_ = std::string_view();
      return;
    }
    if (*next_ == '\\') {
      ++next_;
      if (*next_ == '\0') {
        AddError() << "Unterminated string.\n";
        current_lexical_token_ = LexicalToken::kString;
        next_ = start;
        current_string_ = std::string_view();
        return;
      }
    }
    ++next_;
  }
  current_string_ = std::string_view(&*start, next_ - start);
  ++next_;
  current_lexical_token_ = LexicalToken::kString;
}

}  // namespace semantic
}  // namespace fidl_codec
