// Copyright 2017-2020 The Verible Authors.
//
// 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 "verilog/transform/strip_comments.h"

#include <iostream>
#include <vector>

#include "absl/strings/str_split.h"
#include "common/strings/comment_utils.h"
#include "common/strings/range.h"
#include "common/text/token_info.h"
#include "common/util/iterator_range.h"
#include "common/util/spacer.h"
#include "verilog/parser/verilog_lexer.h"
#include "verilog/parser/verilog_parser.h"
#include "verilog/parser/verilog_token_enum.h"

namespace verilog {

using verible::make_string_view_range;
using verible::Spacer;
using verible::StripComment;
using verible::TokenInfo;

// Replace non-newline characters with a single char, like <space>.
// Tabs are considered non-newline characters.
static void ReplaceNonNewlines(absl::string_view text, std::ostream *output,
                               char replacement) {
  if (text.empty()) return;
  const std::vector<absl::string_view> lines(
      absl::StrSplit(text, absl::ByChar('\n')));
  // no newline before first element
  *output << Spacer(lines.front().size(), replacement);
  for (const auto &line : verible::make_range(lines.begin() + 1, lines.end())) {
    *output << '\n' << Spacer(line.size(), replacement);
  }
}

void StripVerilogComments(absl::string_view content, std::ostream *output,
                          char replacement) {
  VLOG(1) << __FUNCTION__;
  verilog::VerilogLexer lexer(content);

  const TokenInfo::Context context(content, [](std::ostream &stream, int e) {
    stream << verilog_symbol_name(e);
  });

  for (;;) {
    const verible::TokenInfo &token(lexer.DoNextToken());
    if (token.isEOF()) break;

    VLOG(2) << "token: " << verible::TokenWithContext{token, context};
    const absl::string_view text = token.text();
    switch (token.token_enum()) {
      case verilog_tokentype::TK_EOL_COMMENT:
        switch (replacement) {
          case '\0':
            // There is always a '\n' that follows, so there is no risk of
            // accidentally fusing tokens by deleting these comments.
            break;
          case ' ':
            // The lexer guarantees the text does not contain '\n'.
            *output << Spacer(text.length());
            break;
          default: {
            // Retain the "//" but erase everything thereafter.
            const absl::string_view body(StripComment(text));
            const absl::string_view head(
                make_string_view_range(text.begin(), body.begin()));
            *output << head << Spacer(body.length(), replacement);
            break;
          }
        }
        break;

      case verilog_tokentype::TK_COMMENT_BLOCK:
        switch (replacement) {
          case '\0':
            // Print one space to prevent accidental token fusion in
            // cases like: "a/**/b".
            *output << ' ';
            break;
          case ' ':
            // Preserve newlines, but replace everything else with space.
            ReplaceNonNewlines(text, output, replacement);
            break;
          default: {
            // Retain the "/*" and "*/" but erase everything in between.
            const absl::string_view body(StripComment(text));
            const absl::string_view head(
                make_string_view_range(text.begin(), body.begin()));
            const absl::string_view tail(
                make_string_view_range(body.end(), text.end()));

            *output << head;
            ReplaceNonNewlines(body, output, replacement);
            *output << tail;
            break;
          }
        }
        break;
      // The following tokens are un-lexed, so they need to be lexed
      // recursively.
      case verilog_tokentype::MacroArg:
      case verilog_tokentype::PP_define_body:
        StripVerilogComments(text, output, replacement);
        break;
      default:
        // Preserve all other text, including lexical error tokens.
        *output << text;
    }  // switch
  }
  VLOG(1) << "end of " << __FUNCTION__;
}

}  // namespace verilog
