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

#include "Diagnostics.h"
#include "LoadedApk.h"
#include "ValueVisitor.h"
#include "android-base/macros.h"
#include "process/IResourceTableConsumer.h"
#include "process/SymbolTable.h"

using ::android::StringPiece;

namespace aapt {

class DiffContext : public IAaptContext {
 public:
  explicit DiffContext(bool ignore_id_shift)
      : ignore_id_shift(ignore_id_shift), name_mangler_({}), symbol_table_(&name_mangler_) {
  }

  PackageType GetPackageType() override {
    // Doesn't matter.
    return PackageType::kApp;
  }

  const std::string& GetCompilationPackage() override {
    return empty_;
  }

  uint8_t GetPackageId() override {
    return 0x0;
  }

  android::IDiagnostics* GetDiagnostics() override {
    return &diagnostics_;
  }

  NameMangler* GetNameMangler() override {
    return &name_mangler_;
  }

  SymbolTable* GetExternalSymbols() override {
    return &symbol_table_;
  }

  bool IsVerbose() override {
    return false;
  }

  int GetMinSdkVersion() override {
    return 0;
  }

  const std::set<std::string>& GetSplitNameDependencies() override {
    UNIMPLEMENTED(FATAL) << "Split Name Dependencies should not be necessary";
    static std::set<std::string> empty;
    return empty;
  }

  const bool ignore_id_shift;

 private:
  std::string empty_;
  StdErrDiagnostics diagnostics_;
  NameMangler name_mangler_;
  SymbolTable symbol_table_;
};

static void EmitDiffLine(const android::Source& source, StringPiece message) {
  std::cout << source << ": " << message << "\n";
}

static bool IsSymbolVisibilityDifferent(const Visibility& vis_a, const Visibility& vis_b) {
  return vis_a.level != vis_b.level || vis_a.staged_api != vis_b.staged_api;
}

template <typename Id>
static bool IsIdDiff(const Visibility::Level& level_a, const std::optional<Id>& id_a,
                     const Visibility::Level& level_b, const std::optional<Id>& id_b) {
  if (level_a == Visibility::Level::kPublic || level_b == Visibility::Level::kPublic) {
    return id_a != id_b;
  }
  return false;
}

class ZeroingIdVisitor : public DescendingValueVisitor {
 public:
  using DescendingValueVisitor::Visit;

  void Visit(Reference* ref) override {
    if (ref->name) {
      ref->id.reset();
    }
  }
};

static std::unique_ptr<Value> CloneAndClearIds(const Value* value, LoadedApk* apk) {
  CloningValueTransformer cloner(&apk->GetResourceTable()->string_pool);
  auto res = value->Transform(cloner);
  ZeroingIdVisitor visitor;
  res->Accept(&visitor);
  return res;
}

static bool EmitResourceConfigValueDiff(
    DiffContext* context, LoadedApk* apk_a, const ResourceTablePackageView& pkg_a,
    const ResourceTableTypeView& type_a, const ResourceTableEntryView& entry_a,
    const ResourceConfigValue* config_value_a, LoadedApk* apk_b,
    const ResourceTablePackageView& pkg_b, const ResourceTableTypeView& type_b,
    const ResourceTableEntryView& entry_b, const ResourceConfigValue* config_value_b) {
  Value* value_a = config_value_a->value.get();
  Value* value_b = config_value_b->value.get();
  if (!value_a->Equals(value_b)) {
    if (context->ignore_id_shift) {
      // Check if the values are only different because of their IDs
      auto cleared_a = CloneAndClearIds(value_a, apk_a);
      auto cleared_b = CloneAndClearIds(value_b, apk_b);
      if (cleared_a->Equals(cleared_b.get())) {
        return false;
      }
    }
    std::stringstream str_stream;
    str_stream << "value " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
               << " config='" << config_value_a->config << "' does not match:\n";
    value_a->Print(&str_stream);
    str_stream << "\n vs \n";
    value_b->Print(&str_stream);
    EmitDiffLine(apk_b->GetSource(), str_stream.str());
    return true;
  }
  return false;
}

static bool EmitResourceEntryDiff(DiffContext* context, LoadedApk* apk_a,
                                  const ResourceTablePackageView& pkg_a,
                                  const ResourceTableTypeView& type_a,
                                  const ResourceTableEntryView& entry_a, LoadedApk* apk_b,
                                  const ResourceTablePackageView& pkg_b,
                                  const ResourceTableTypeView& type_b,
                                  const ResourceTableEntryView& entry_b) {
  bool diff = false;
  for (const ResourceConfigValue* config_value_a : entry_a.values) {
    auto config_value_b = entry_b.FindValue(config_value_a->config);
    if (!config_value_b) {
      std::stringstream str_stream;
      str_stream << "missing " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                 << " config=" << config_value_a->config;
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    } else {
      diff |= EmitResourceConfigValueDiff(context, apk_a, pkg_a, type_a, entry_a, config_value_a,
                                          apk_b, pkg_b, type_b, entry_b, config_value_b);
    }
  }

  for (const ResourceConfigValue* config_value_a : entry_a.flag_disabled_values) {
    auto config_value_b = entry_b.FindFlagDisabledValue(config_value_a->value->GetFlag().value(),
                                                        config_value_a->config);
    if (!config_value_b) {
      std::stringstream str_stream;
      str_stream << "missing disabled value " << pkg_a.name << ":" << type_a.named_type << "/"
                 << entry_a.name << " config=" << config_value_a->config
                 << " flag=" << config_value_a->value->GetFlag()->ToString();
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    } else {
      diff |= EmitResourceConfigValueDiff(context, apk_a, pkg_a, type_a, entry_a, config_value_a,
                                          apk_b, pkg_b, type_b, entry_b, config_value_b);
    }
  }

  for (const ResourceConfigValue* config_value_a : entry_a.readwrite_flag_values) {
    auto config_value_b = entry_b.FindReadWriteFlagValue(config_value_a->value->GetFlag().value(),
                                                         config_value_a->config);
    if (!config_value_b) {
      std::stringstream str_stream;
      str_stream << "missing read/write flag value " << pkg_a.name << ":" << type_a.named_type
                 << "/" << entry_a.name << " config=" << config_value_a->config
                 << " flag=" << config_value_a->value->GetFlag()->ToString();
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    } else {
      diff |= EmitResourceConfigValueDiff(context, apk_a, pkg_a, type_a, entry_a, config_value_a,
                                          apk_b, pkg_b, type_b, entry_b, config_value_b);
    }
  }

  // Check for any newly added config values.
  for (const ResourceConfigValue* config_value_b : entry_b.values) {
    auto config_value_a = entry_a.FindValue(config_value_b->config);
    if (!config_value_a) {
      std::stringstream str_stream;
      str_stream << "new config " << pkg_b.name << ":" << type_b.named_type << "/" << entry_b.name
                 << " config=" << config_value_b->config;
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    }
  }
  for (const ResourceConfigValue* config_value_b : entry_b.flag_disabled_values) {
    auto config_value_a = entry_a.FindFlagDisabledValue(config_value_b->value->GetFlag().value(),
                                                        config_value_b->config);
    if (!config_value_a) {
      std::stringstream str_stream;
      str_stream << "new disabled config " << pkg_b.name << ":" << type_b.named_type << "/"
                 << entry_b.name << " config=" << config_value_b->config
                 << " flag=" << config_value_b->value->GetFlag()->ToString();
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    }
  }
  for (const ResourceConfigValue* config_value_b : entry_b.readwrite_flag_values) {
    auto config_value_a = entry_a.FindReadWriteFlagValue(config_value_b->value->GetFlag().value(),
                                                         config_value_b->config);
    if (!config_value_a) {
      std::stringstream str_stream;
      str_stream << "new read/write flag config " << pkg_b.name << ":" << type_b.named_type << "/"
                 << entry_b.name << " config=" << config_value_b->config
                 << " flag=" << config_value_b->value->GetFlag()->ToString();
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    }
  }
  return diff;
}

static const ResourceTableEntryView* findEntry(const ResourceTableTypeView& type,
                                               const ResourceTableEntryView& entry) {
  auto it = std::ranges::find_if(type.entries, [&](const ResourceTableEntryView& other_entry) {
    return other_entry.name == entry.name;
  });
  return it != std::end(type.entries) ? &*it : nullptr;
}

static bool EmitResourceTypeDiff(DiffContext* context, LoadedApk* apk_a,
                                 const ResourceTablePackageView& pkg_a,
                                 const ResourceTableTypeView& type_a, LoadedApk* apk_b,
                                 const ResourceTablePackageView& pkg_b,
                                 const ResourceTableTypeView& type_b) {
  bool diff = false;
  std::unordered_set<const ResourceTableEntryView*> found_b_entries;
  for (auto&& entry_a : type_a.entries) {
    auto entry_b_iter = findEntry(type_b, entry_a);
    if (!entry_b_iter) {
      // Type A contains a type that type B does not have.
      std::stringstream str_stream;
      str_stream << "missing " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name;
      EmitDiffLine(apk_a->GetSource(), str_stream.str());
      diff = true;
      continue;
    }
    const auto& entry_b = *entry_b_iter;
    found_b_entries.insert(&entry_b);
    if (IsSymbolVisibilityDifferent(entry_a.visibility, entry_b.visibility)) {
      std::stringstream str_stream;
      str_stream << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                 << " has different visibility (";
      if (entry_b.visibility.staged_api) {
        str_stream << "STAGED ";
      }
      if (entry_b.visibility.level == Visibility::Level::kPublic) {
        str_stream << "PUBLIC";
      } else {
        str_stream << "PRIVATE";
      }
      str_stream << " vs ";
      if (entry_a.visibility.staged_api) {
        str_stream << "STAGED ";
      }
      if (entry_a.visibility.level == Visibility::Level::kPublic) {
        str_stream << "PUBLIC";
      } else {
        str_stream << "PRIVATE";
      }
      str_stream << ")";
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    } else if (!context->ignore_id_shift && IsIdDiff(entry_a.visibility.level, entry_a.id,
                                                     entry_b.visibility.level, entry_b.id)) {
      std::stringstream str_stream;
      str_stream << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                 << " has different public ID (";
      if (entry_b.id) {
        str_stream << "0x" << std::hex << entry_b.id.value();
      } else {
        str_stream << "none";
      }
      str_stream << " vs ";
      if (entry_a.id) {
        str_stream << "0x " << std::hex << entry_a.id.value();
      } else {
        str_stream << "none";
      }
      str_stream << ")";
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    }
    diff |= EmitResourceEntryDiff(context, apk_a, pkg_a, type_a, entry_a, apk_b, pkg_b, type_b,
                                  entry_b);
  }
  if (found_b_entries.size() < type_b.entries.size()) {
    diff = true;
    for (auto&& entry_b : type_b.entries) {
      if (found_b_entries.contains(&entry_b)) {
        continue;
      }
      // Type B contains a type that type A does not have.
      std::stringstream str_stream;
      str_stream << "new entry " << pkg_b.name << ":" << type_b.named_type << "/" << entry_b.name;
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
    }
  }
  return diff;
}

static bool EmitResourcePackageDiff(DiffContext* context, LoadedApk* apk_a,
                                    const ResourceTablePackageView& pkg_a, LoadedApk* apk_b,
                                    const ResourceTablePackageView& pkg_b) {
  bool diff = false;
  auto type_a_iter = pkg_a.types.begin();
  auto type_b_iter = pkg_b.types.begin();
  while (type_a_iter != pkg_a.types.end() || type_b_iter != pkg_b.types.end()) {
    if (type_b_iter == pkg_b.types.end()) {
      // Type A contains a type that type B does not have.
      std::stringstream str_stream;
      str_stream << "missing " << pkg_a.name << ":" << type_a_iter->named_type;
      EmitDiffLine(apk_a->GetSource(), str_stream.str());
      diff = true;
    } else if (type_a_iter == pkg_a.types.end()) {
      // Type B contains a type that type A does not have.
      std::stringstream str_stream;
      str_stream << "new type " << pkg_b.name << ":" << type_b_iter->named_type;
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    } else {
      const auto& type_a = *type_a_iter;
      const auto& type_b = *type_b_iter;
      if (type_a.visibility_level != type_b.visibility_level) {
        std::stringstream str_stream;
        str_stream << pkg_a.name << ":" << type_a.named_type << " has different visibility (";
        if (type_b.visibility_level == Visibility::Level::kPublic) {
          str_stream << "PUBLIC";
        } else {
          str_stream << "PRIVATE";
        }
        str_stream << " vs ";
        if (type_a.visibility_level == Visibility::Level::kPublic) {
          str_stream << "PUBLIC";
        } else {
          str_stream << "PRIVATE";
        }
        str_stream << ")";
        EmitDiffLine(apk_b->GetSource(), str_stream.str());
        diff = true;
      } else if (!context->ignore_id_shift &&
                 IsIdDiff(type_a.visibility_level, type_a.id, type_b.visibility_level, type_b.id)) {
        std::stringstream str_stream;
        str_stream << pkg_a.name << ":" << type_a.named_type << " has different public ID (";
        if (type_b.id) {
          str_stream << "0x" << std::hex << type_b.id.value();
        } else {
          str_stream << "none";
        }
        str_stream << " vs ";
        if (type_a.id) {
          str_stream << "0x " << std::hex << type_a.id.value();
        } else {
          str_stream << "none";
        }
        str_stream << ")";
        EmitDiffLine(apk_b->GetSource(), str_stream.str());
        diff = true;
      }
      diff |= EmitResourceTypeDiff(context, apk_a, pkg_a, type_a, apk_b, pkg_b, type_b);
    }
    if (type_a_iter != pkg_a.types.end()) {
      ++type_a_iter;
    }
    if (type_b_iter != pkg_b.types.end()) {
      ++type_b_iter;
    }
  }
  return diff;
}

static bool EmitResourceTableDiff(DiffContext* context, LoadedApk* apk_a, LoadedApk* apk_b) {
  const auto table_a = apk_a->GetResourceTable()->GetPartitionedView();
  const auto table_b = apk_b->GetResourceTable()->GetPartitionedView();

  bool diff = false;
  auto package_a_iter = table_a.packages.begin();
  auto package_b_iter = table_b.packages.begin();
  while (package_a_iter != table_a.packages.end() || package_b_iter != table_b.packages.end()) {
    if (package_b_iter == table_b.packages.end()) {
      // Table A contains a package that table B does not have.
      std::stringstream str_stream;
      str_stream << "missing package " << package_a_iter->name;
      EmitDiffLine(apk_a->GetSource(), str_stream.str());
      diff = true;
    } else if (package_a_iter == table_a.packages.end()) {
      // Table B contains a package that table A does not have.
      std::stringstream str_stream;
      str_stream << "new package " << package_b_iter->name;
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    } else {
      const auto& package_a = *package_a_iter;
      const auto& package_b = *package_b_iter;
      if (package_a.id != package_b.id && !context->ignore_id_shift) {
        std::stringstream str_stream;
        str_stream << "package '" << package_a.name << "' has different id (";
        if (package_b.id) {
          str_stream << "0x" << std::hex << package_b.id.value();
        } else {
          str_stream << "none";
        }
        str_stream << " vs ";
        if (package_a.id) {
          str_stream << "0x" << std::hex << package_b.id.value();
        } else {
          str_stream << "none";
        }
        str_stream << ")";
        EmitDiffLine(apk_b->GetSource(), str_stream.str());
        diff = true;
      }
      diff |= EmitResourcePackageDiff(context, apk_a, package_a, apk_b, package_b);
    }
    if (package_a_iter != table_a.packages.end()) {
      ++package_a_iter;
    }
    if (package_b_iter != table_b.packages.end()) {
      ++package_b_iter;
    }
  }

  return diff;
}

class ZeroingReferenceVisitor : public DescendingValueVisitor {
 public:
  using DescendingValueVisitor::Visit;

  void Visit(Reference* ref) override {
    if (ref->name && ref->id) {
      if (ref->id.value().package_id() == kAppPackageId) {
        ref->id = {};
      }
    }
  }
};

static void ZeroOutAppReferences(ResourceTable* table) {
  ZeroingReferenceVisitor visitor;
  VisitAllValuesInTable(table, &visitor);
}

int DiffCommand::Action(const std::vector<std::string>& args) {
  DiffContext context(ignore_id_shift_);

  if (args.size() != 2u) {
    std::cerr << "must have two apks as arguments.\n\n";
    Usage(&std::cerr);
    return 1;
  }

  android::IDiagnostics* diag = context.GetDiagnostics();
  std::unique_ptr<LoadedApk> apk_a = LoadedApk::LoadApkFromPath(args[0], diag);
  std::unique_ptr<LoadedApk> apk_b = LoadedApk::LoadApkFromPath(args[1], diag);
  if (!apk_a || !apk_b) {
    return 1;
  }

  // Zero out Application IDs in references.
  ZeroOutAppReferences(apk_a->GetResourceTable());
  ZeroOutAppReferences(apk_b->GetResourceTable());

  if (EmitResourceTableDiff(&context, apk_a.get(), apk_b.get())) {
    // We emitted a diff, so return 1 (failure).
    return 1;
  }
  return 0;
}

}  // namespace aapt
