/*
 * Copyright (C) 2020 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 "TypeChecker.h"

#include <algorithm>
#include <string>
#include <unordered_map>

#include <android-base/strings.h>

#include "Common.h"

using android::base::Result;
using android::properties::ParsePropertyInfoFile;
using android::properties::PropertyInfoEntry;

namespace {
std::string SyspropTypeToContextType(const sysprop::Property& prop) {
  switch (prop.type()) {
    case sysprop::Integer:
    case sysprop::Long:
      return "int";
    case sysprop::Double:
      return "double";
    case sysprop::Boolean:
      return "bool";
    case sysprop::Enum: {
      // Sort both values and then join
      auto prop_values = android::base::Split(prop.enum_values(), "|");
      std::sort(prop_values.begin(), prop_values.end());
      return "enum " + android::base::Join(prop_values, " ");
    }
    default:
      // All other types (string, all kinds of list) should fall here
      return "string";
  }
}

bool IsCompatible(const sysprop::Property& prop, const std::string& ctx_type) {
  if (prop.type() == sysprop::Enum) {
    // special case: we need to first sort values and then compare
    auto prop_values = ParseEnumValues(prop.enum_values());
    std::sort(prop_values.begin(), prop_values.end());

    // ctx_type must be "enum [value1] [value2] ..."
    auto ctx_values = android::base::Split(ctx_type, " ");
    if (ctx_values.empty() || ctx_values[0] != "enum") {
      return false;
    }
    ctx_values.erase(ctx_values.begin());
    std::sort(ctx_values.begin(), ctx_values.end());

    return prop_values == ctx_values;
  }

  return SyspropTypeToContextType(prop) == ctx_type;
}

std::string GetTypeName(const sysprop::Property& prop) {
  if (prop.type() == sysprop::Enum) {
    return "Enum " + prop.enum_values();
  }

  return sysprop::Type_Name(prop.type());
}
}  // namespace

Result<void> CheckPropertyTypes(const sysprop::SyspropLibraryApis& api,
                                const std::vector<PropertyInfoEntry>& entries) {
  std::string err;

  // map from exact property names to types in property_contexts
  std::unordered_map<std::string, std::string> types;
  for (auto& entry : entries) {
    // skip prefix entries.
    if (!entry.exact_match) continue;

    // Duplicated prop check is intentionally skipped.
    // Build will fail if any duplication happens.
    types.emplace(entry.name, entry.type);
  }

  for (auto& props : api.props()) {
    for (auto& prop : props.prop()) {
      std::vector<std::string> prop_names{prop.prop_name()};
      std::string legacy_name = prop.legacy_prop_name();
      if (!legacy_name.empty()) prop_names.push_back(legacy_name);

      for (auto& prop_name : prop_names) {
        // Skip check if there is no exactly matched property.
        auto itr = types.find(prop_name);
        if (itr == types.end()) continue;

        if (!IsCompatible(prop, itr->second)) {
          if (!err.empty()) err += "\n";
          err += "Type of prop '" + prop_name +
                 "' is incompatible with property_contexts\n";
          err += "In sysprop_library: " + GetTypeName(prop) + "\n";
          err += "In property_contexts: " + itr->second + " (should be '" +
                 SyspropTypeToContextType(prop) + "')\n";
        }
      }
    }
  }

  if (err.empty())
    return {};
  else
    return Errorf("{}", err);
}
