/*
 * 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::Errorf;
using android::base::Result;

namespace {

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

  for (int i = 0; i < current.prop_size(); ++i) {
    const auto& prop = current.prop(i);
    props[prop.api_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()) {
      continue;
    }

    latest_empty = false;

    auto itr = props.find(latest_prop.api_name());
    if (itr == props.end()) {
      err += "Prop " + latest_prop.api_name() + " has been removed\n";
      continue;
    }

    const auto& current_prop = itr->second;

    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.prop_name() != current_prop.prop_name()) {
      err += "Underlying property of prop " + latest_prop.api_name() +
             " has been changed\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 (!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) {
      return res;
    }
  }

  return {};
}
