// 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 "common/text/token_info_test_util.h"

#include <algorithm>
#include <initializer_list>
#include <iterator>
#include <ostream>
#include <vector>

#include "absl/strings/string_view.h"
#include "common/text/token_info.h"
#include "common/util/logging.h"

namespace verible {

ExpectedTokenInfo::ExpectedTokenInfo(char token_enum_and_text)
    : TokenInfo(static_cast<int>(token_enum_and_text),
                // Point the string_view to the sub-byte of token_enum that
                // holds the single character value (which also acts as the
                // enum). View the (int) token_enum as a sequence of characters.
                // Depending on the endianness of the underlying machine,
                // the desired byte will be (relative to the reinterpreted base
                // address) at offset 0 or sizeof(int) -1.
                // Note: This constructor using a self-pointer makes this struct
                // non-default-copy/move/assign-able.
                absl::string_view(reinterpret_cast<const char*>(&token_enum_)
#ifdef IS_BIG_ENDIAN
                                      + (sizeof(typeid(token_enum_)) - 1)
#endif
                                      ,
                                  1)) {
}

TokenInfoTestData::TokenInfoTestData(
    std::initializer_list<ExpectedTokenInfo> fragments) {
  // Trivially convert ExpectedTokenInfo into TokenInfo.
  // TODO(fangism): For tokens that use the single (char) construction,
  // this copying operation will leave new TokenInfos' text pointing into
  // the source ExpectedTokenInfos' token_enums.  (Deleting the standard
  // interfaces in ExpectedTokenInfo alone does not prevent this.)
  // Under most circumstances, this leakage would be deemed dangerous
  // and unintended, however, since fragments is passed in as an
  // initializer_list (a const-T proxy to a longer-lived memory),
  // this operates safely.  The alternative would be to perform a fix-up over
  // the copy destination array.
  expected_tokens.resize(fragments.size(), TokenInfo::EOFToken());
  std::copy(fragments.begin(), fragments.end(), expected_tokens.begin());

  // Construct the whole text to lex from fragments.
  TokenInfo::Concatenate(&code, &expected_tokens);
}

std::vector<TokenInfo> TokenInfoTestData::FindImportantTokens() const {
  std::vector<TokenInfo> return_tokens;
  std::copy_if(expected_tokens.begin(), expected_tokens.end(),
               std::back_inserter(return_tokens), [](const TokenInfo& t) {
                 return t.token_enum() != ExpectedTokenInfo::kDontCare;
               });
  return return_tokens;
}

std::vector<TokenInfo> TokenInfoTestData::FindImportantTokens(
    absl::string_view base) const {
  std::vector<TokenInfo> return_tokens = FindImportantTokens();
  RebaseToCodeCopy(&return_tokens, base);
  return return_tokens;
}

void TokenInfoTestData::RebaseToCodeCopy(std::vector<TokenInfo>* tokens,
                                         absl::string_view base) const {
  CHECK_EQ(code, base);  // verify content match
  // Another analyzer object may have made its own copy of 'code', so
  // we need to translate the expected error token into a rebased version
  // before directly comparing against the rejected tokens.
  for (TokenInfo& token : *tokens) {
    const auto offset =
        std::distance(absl::string_view(code).begin(), token.text().begin());
    token.RebaseStringView(base.begin() + offset);
  }
}

}  // namespace verible
