// 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"

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::const_iterator start_line = location.buffer().begin();
  int line = 1;
  int column = 1;
  std::string::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;
    }
    Interface* interface = nullptr;
    if (library != nullptr) {
      std::string protocol_name = library->name() + "/" + std::string(current_string_);
      if (!library->GetInterfaceByName(protocol_name, &interface)) {
        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;
    }
    InterfaceMethod* method = nullptr;
    if (interface != nullptr) {
      method = interface->GetMethodByName(current_string_);
      if (method == nullptr) {
        AddError() << "Method " << current_string_ << " not found in protocol " << interface->name()
                   << '\n';
      }
    }
    NextLexicalToken();
    if (!ParseLeftBrace()) {
      SkipBlock();
      NextLexicalToken();
      return;
    }
    ParseMethod(method);
  }
}

void SemanticParser::ParseMethod(InterfaceMethod* 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::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::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(&*start, 0);
      return;
    }
    if (*next_ == '\\') {
      ++next_;
      if (*next_ == '\0') {
        AddError() << "Unterminated string.\n";
        current_lexical_token_ = LexicalToken::kString;
        next_ = start;
        current_string_ = std::string_view(&*start, 0);
        return;
      }
    }
    ++next_;
  }
  current_string_ = std::string_view(&*start, next_ - start);
  ++next_;
  current_lexical_token_ = LexicalToken::kString;
}

}  // namespace semantic
}  // namespace fidl_codec
