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

#include <string>
#include <unordered_map>

using android::base::Result;

namespace {

Result<void> CompareProps(const sysprop::Properties& latest,
                          const sysprop::Properties& current) {
  std::unordered_map<std::string, sysprop::Property> props;
  std::unordered_map<std::string, sysprop::Property> legacy_props;

  for (int i = 0; i < current.prop_size(); ++i) {
    const auto& prop = current.prop(i);
    props[prop.api_name()] = prop;
    if (!prop.legacy_prop_name().empty()) {
      legacy_props[prop.legacy_prop_name()] = prop;
    }
  }

  std::string err;

  bool latest_empty = true;
  for (int i = 0; i < latest.prop_size(); ++i) {
    const auto& latest_prop = latest.prop(i);
    if (latest_prop.deprecated() || latest_prop.scope() == sysprop::Internal) {
      continue;
    }

    latest_empty = false;

    // Error if a prop from the latest API doesn't exist in the current API.
    // But allow removal if any legacy_prop_name in the current API is
    // identical to prop_name.
    bool legacy = false;
    auto itr = props.find(latest_prop.api_name());
    sysprop::Property current_prop;
    if (itr != props.end()) {
      current_prop = itr->second;
    } else {
      auto legacy_itr = legacy_props.find(latest_prop.prop_name());
      if (legacy_itr != legacy_props.end()) {
        legacy = true;
        current_prop = legacy_itr->second;
      } else {
        err += "Prop " + latest_prop.api_name() + " has been removed\n";
        continue;
      }
    }

    if (latest_prop.type() != current_prop.type()) {
      err += "Type of prop " + latest_prop.api_name() + " has been changed\n";
    }
    // Readonly > Writeonce > ReadWrite
    if (latest_prop.access() > current_prop.access()) {
      err += "Accessibility of prop " + latest_prop.api_name() +
             " has become more restrictive\n";
    }
    // Public < Internal
    if (latest_prop.scope() < current_prop.scope()) {
      err += "Scope of prop " + latest_prop.api_name() +
             " has become more restrictive\n";
    }
    if (latest_prop.enum_values() != current_prop.enum_values()) {
      err += "Enum values of prop " + latest_prop.api_name() +
             " has been changed\n";
    }
    if (latest_prop.integer_as_bool() != current_prop.integer_as_bool()) {
      err += "Integer-as-bool of prop " + latest_prop.api_name() +
             " has been changed\n";
    }
    // If current_prop is new and latest_prop is legacy, skip prop name compare
    // because latest_prop.prop_name() == current_prop.legacy_prop_name()
    if (!legacy) {
      if (latest_prop.prop_name() != current_prop.prop_name()) {
        err += "Underlying property of prop " + latest_prop.api_name() +
               " has been changed\n";
      }
      if (latest_prop.legacy_prop_name() != current_prop.legacy_prop_name()) {
        err += "Legacy prop of prop " + latest_prop.api_name() +
               " has been changed\n";
      }
    }
  }

  if (!latest_empty) {
    if (latest.owner() != current.owner()) {
      err += "owner of module " + latest.module() + " has been changed\n";
    }
  }

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

}  // namespace

Result<void> CompareApis(const sysprop::SyspropLibraryApis& latest,
                         const sysprop::SyspropLibraryApis& current) {
  std::unordered_map<std::string, sysprop::Properties> propsMap;

  for (int i = 0; i < current.props_size(); ++i) {
    propsMap[current.props(i).module()] = current.props(i);
  }

  for (int i = 0; i < latest.props_size(); ++i) {
    // Checking whether propsMap contains latest.props(i)->module() or not
    // is intentionally skipped to handle the case that latest.props(i) has
    // only deprecated properties.
    if (auto res =
            CompareProps(latest.props(i), propsMap[latest.props(i).module()]);
        !res.ok()) {
      return res;
    }
  }

  return {};
}
