/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 "SymbolFileParser.h"

#include "Arch.h"
#include "CompilationType.h"

#include <android-base/strings.h>

#include <fstream>
#include <ios>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>

#include <err.h>

namespace {

using TagList = std::vector<std::string>;

struct SymbolEnt {
  std::string name;
  TagList tags;
};

using SymbolList = std::vector<SymbolEnt>;

struct Version {
  std::string name;
  std::string base;
  SymbolList symbols;
  TagList tags;
};

class SymbolFileParser {
 public:
  SymbolFileParser(const std::string& path, const CompilationType& type)
    : file_path(path),
      compilation_type(type),
      api_level_arch_prefix("api-level-" + to_string(type.arch) + "="),
      intro_arch_perfix("introduced-" + to_string(type.arch) + "="),
      file(path, std::ios_base::in),
      curr_line_num(0) {
  }

  // Parse the version script and build a symbol map.
  std::optional<SymbolMap> parse() {
    if (!file) {
      return std::nullopt;
    }

    SymbolMap symbol_map;
    while (hasNextLine()) {
      auto&& version = parseVersion();
      if (!version) {
        return std::nullopt;
      }

      if (isInArch(version->tags) && isInApi(version->tags)) {
        for (auto&& [name, tags] : version->symbols) {
          if (isInArch(tags) && isInApi(tags)) {
            symbol_map[name] = getSymbolType(tags);
          }
        }
      }
    }
    return std::make_optional(std::move(symbol_map));
  }

 private:
  // Read a non-empty line from the input and split at the first '#' character.
  bool hasNextLine() {
    std::string line;
    while (std::getline(file, line)) {
      ++curr_line_num;

      size_t hash_pos = line.find('#');
      curr_line = android::base::Trim(line.substr(0, hash_pos));
      if (!curr_line.empty()) {
        if (hash_pos != std::string::npos) {
          curr_tags = parseTags(line.substr(hash_pos + 1));
        } else {
          curr_tags.clear();
        }
        return true;
      }
    }
    return false;
  }

  // Tokenize the tags after the '#' character.
  static std::vector<std::string> parseTags(const std::string& tags_line) {
    std::vector<std::string> tags = android::base::Split(tags_line, " \t");
    tags.erase(std::remove(tags.begin(), tags.end(), ""), tags.end());
    return tags;
  }

  // Parse a version scope.
  std::optional<Version> parseVersion() {
    size_t start_line_num = curr_line_num;

    std::string::size_type lparen_pos = curr_line.find('{');
    if (lparen_pos == std::string::npos) {
      errx(1, "%s:%zu: error: expected '{' cannot be found in this line",
           file_path.c_str(), curr_line_num);
    }

    // Record the version name and version tags (before hasNextLine()).
    std::string name = android::base::Trim(curr_line.substr(0, lparen_pos));
    TagList tags = std::move(curr_tags);

    // Read symbol lines.
    SymbolList symbols;
    bool global_scope = true;
    bool cpp_scope = false;
    while (hasNextLine()) {
      size_t rparen_pos = curr_line.find('}');
      if (rparen_pos != std::string::npos) {
        size_t semicolon_pos = curr_line.find(';', rparen_pos + 1);
        if (semicolon_pos == std::string::npos) {
          errx(1, "%s:%zu: error: the line that ends a scope must end with ';'",
               file_path.c_str(), curr_line_num);
        }

        if (cpp_scope) {
          cpp_scope = false;
          continue;
        }

        std::string base = android::base::Trim(
          curr_line.substr(rparen_pos + 1, semicolon_pos - 1));

        return std::make_optional(Version{std::move(name), std::move(base),
                                          std::move(symbols), std::move(tags)});
      }

      if (android::base::StartsWith(curr_line, R"(extern "C++" {)")) {
        cpp_scope = true;
        continue;
      }

      if (cpp_scope) {
        continue;
      }

      size_t colon_pos = curr_line.find(':');
      if (colon_pos != std::string::npos) {
        std::string visibility =
          android::base::Trim(curr_line.substr(0, colon_pos));

        if (visibility == "global") {
          global_scope = true;
        } else if (visibility == "local") {
          global_scope = false;
        } else {
          errx(1, "%s:%zu: error: unknown version visibility: %s",
               file_path.c_str(), curr_line_num, visibility.c_str());
        }
        continue;
      }

      if (global_scope) {
        size_t semicolon_pos = curr_line.find(';');
        if (semicolon_pos == std::string::npos) {
          errx(1, "%s:%zu: error: symbol name line must end with ';'",
               file_path.c_str(), curr_line_num);
        }

        std::string symbol_name =
          android::base::Trim(curr_line.substr(0, semicolon_pos));

        size_t asterisk_pos = symbol_name.find('*');
        if (asterisk_pos != std::string::npos) {
          errx(1, "%s:%zu: error: global symbol name must not have wildcards",
               file_path.c_str(), curr_line_num);
        }

        symbols.push_back(SymbolEnt{std::move(symbol_name),
                                    std::move(curr_tags)});
      }
    }

    errx(1, "%s:%zu: error: scope started from %zu must be closed before EOF",
         file_path.c_str(), curr_line_num, start_line_num);
  }

  static NdkSymbolType getSymbolType(const TagList& tags) {
    for (auto&& tag : tags) {
      if (tag == "var") {
        return NdkSymbolType::variable;
      }
    }
    return NdkSymbolType::function;
  }

  // isInArch() returns true if there is a matching arch-specific tag or there
  // are no arch-specific tags.
  bool isInArch(const TagList& tags) const {
    bool has_arch_tags = false;
    for (auto&& tag : tags) {
      std::optional<Arch> arch = arch_from_string(tag);
      if (!arch) {
        continue;
      }
      if (*arch == compilation_type.arch) {
        return true;
      }
      has_arch_tags = true;
    }
    return !has_arch_tags;
  }

  // isInApi() returns true if the specified API level is equal to the
  // api-level tag, or the specified API level is greater than or equal to the
  // introduced tag, or there are no api-level or introduced tags.
  bool isInApi(const TagList& tags) const {
    bool api_level_arch = false;
    bool intro_arch = false;
    std::string api_level;
    std::string intro;

    for (const std::string& tag : tags) {
      // Check api-level tags.
      if (android::base::StartsWith(tag, "api-level=") && !api_level_arch) {
        api_level = tag;
        continue;
      }
      if (android::base::StartsWith(tag, api_level_arch_prefix)) {
        api_level = tag;
        api_level_arch = true;
        continue;
      }

      // Check introduced tags.
      if (android::base::StartsWith(tag, "introduced=") && !intro_arch) {
        intro = tag;
        continue;
      }
      if (android::base::StartsWith(tag, intro_arch_perfix)) {
        intro = tag;
        intro_arch = true;
        continue;
      }
    }

    if (intro.empty() && api_level.empty()) {
      return true;
    }

    if (!api_level.empty()) {
      // If an api-level tag is specified, it must be an exact match (mainly
      // for versioner unit tests).
      return compilation_type.api_level == parseApiLevelValue(api_level);
    }

    return compilation_type.api_level >= parseApiLevelValue(intro);
  }

  // Parse the integer API level from api-level or introduced tags.
  int parseApiLevelValue(const std::string& tag) const {
    std::string api_level = tag.substr(tag.find('=') + 1);
    auto it = api_codename_map.find(api_level);
    if (it != api_codename_map.end()) {
      return it->second;
    }
    if (api_level.find_first_not_of("0123456789") != std::string::npos) {
      errx(1, "%s:%zu: error: unknown API level codename specified: \"%s\"",
           file_path.c_str(), curr_line_num, tag.c_str());
    }
    return std::stoi(api_level);
  }

 private:
  const std::string& file_path;
  const CompilationType& compilation_type;
  const std::string api_level_arch_prefix;
  const std::string intro_arch_perfix;

  std::ifstream file;
  std::string curr_line;
  std::vector<std::string> curr_tags;
  size_t curr_line_num;
};

}  // anonymous namespace


std::optional<SymbolMap> parseSymbolFile(const std::string& file_path,
                                         const CompilationType& type) {
  SymbolFileParser parser(file_path, type);
  return parser.parse();
}
