/*
 * Copyright (C) 2015 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.
 */

#ifndef AAPT_RESOURCE_TABLE_H
#define AAPT_RESOURCE_TABLE_H

#include "Diagnostics.h"
#include "Resource.h"
#include "ResourceValues.h"
#include "Source.h"
#include "StringPool.h"
#include "io/File.h"

#include "android-base/macros.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/StringPiece.h"

#include <functional>
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;

namespace aapt {

// The Public status of a resource.
struct Visibility {
  enum class Level {
    kUndefined,
    kPrivate,
    kPublic,
  };

  Level level = Level::kUndefined;
  Source source;
  std::string comment;

  // Indicates that the resource id may change across builds and that the public R.java identifier
  // for this resource should not be final. This is set to `true` for resources in `staging-group`
  // tags.
  bool staged_api = false;
};

// Represents <add-resource> in an overlay.
struct AllowNew {
  Source source;
  std::string comment;
};

// Represents the staged resource id of a finalized resource.
struct StagedId {
  ResourceId id;
  Source source;
};

struct Overlayable {
  Overlayable() = default;
   Overlayable(const android::StringPiece& name, const android::StringPiece& actor)
       : name(name.to_string()), actor(actor.to_string()) {}
   Overlayable(const android::StringPiece& name, const android::StringPiece& actor,
                    const Source& source)
       : name(name.to_string()), actor(actor.to_string()), source(source ){}

  static const char* kActorScheme;
  std::string name;
  std::string actor;
  Source source;
};

// Represents a declaration that a resource is overlayable at runtime.
struct OverlayableItem {
  explicit OverlayableItem(const std::shared_ptr<Overlayable>& overlayable)
      : overlayable(overlayable) {}
  std::shared_ptr<Overlayable> overlayable;
  PolicyFlags policies = PolicyFlags::NONE;
  std::string comment;
  Source source;
};

class ResourceConfigValue {
 public:
  // The configuration for which this value is defined.
  const android::ConfigDescription config;

  // The product for which this value is defined.
  const std::string product;

  // The actual Value.
  std::unique_ptr<Value> value;

  ResourceConfigValue(const android::ConfigDescription& config, const android::StringPiece& product)
      : config(config), product(product.to_string()) {}

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue);
};

// Represents a resource entry, which may have varying values for each defined configuration.
class ResourceEntry {
 public:
  // The name of the resource. Immutable, as this determines the order of this resource
  // when doing lookups.
  const std::string name;

  // The entry ID for this resource (the EEEE in 0xPPTTEEEE).
  std::optional<ResourceId> id;

  // Whether this resource is public (and must maintain the same entry ID across builds).
  Visibility visibility;

  std::optional<AllowNew> allow_new;

  // The declarations of this resource as overlayable for RROs
  std::optional<OverlayableItem> overlayable_item;

  // The staged resource id for a finalized resource.
  std::optional<StagedId> staged_id;

  // The resource's values for each configuration.
  std::vector<std::unique_ptr<ResourceConfigValue>> values;

  explicit ResourceEntry(const android::StringPiece& name) : name(name.to_string()) {}

  ResourceConfigValue* FindValue(const android::ConfigDescription& config,
                                 android::StringPiece product = {});
  const ResourceConfigValue* FindValue(const android::ConfigDescription& config,
                                       android::StringPiece product = {}) const;

  ResourceConfigValue* FindOrCreateValue(const android::ConfigDescription& config,
                                         const android::StringPiece& product);
  std::vector<ResourceConfigValue*> FindAllValues(const android::ConfigDescription& config);

  template <typename Func>
  std::vector<ResourceConfigValue*> FindValuesIf(Func f) {
    std::vector<ResourceConfigValue*> results;
    for (auto& config_value : values) {
      if (f(config_value.get())) {
        results.push_back(config_value.get());
      }
    }
    return results;
  }

  bool HasDefaultValue() const;

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceEntry);
};

// Represents a resource type (eg. string, drawable, layout, etc.) containing resource entries.
class ResourceTableType {
 public:
  // The logical type of resource (string, drawable, layout, etc.).
  const ResourceType type;

  // Whether this type is public (and must maintain the same type ID across builds).
  Visibility::Level visibility_level = Visibility::Level::kUndefined;

  // List of resources for this type.
  std::vector<std::unique_ptr<ResourceEntry>> entries;

  explicit ResourceTableType(const ResourceType type) : type(type) {}

  ResourceEntry* CreateEntry(const android::StringPiece& name);
  ResourceEntry* FindEntry(const android::StringPiece& name) const;
  ResourceEntry* FindOrCreateEntry(const android::StringPiece& name);

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
};

class ResourceTablePackage {
 public:
  std::string name;

  std::vector<std::unique_ptr<ResourceTableType>> types;

  explicit ResourceTablePackage(const android::StringPiece& name) : name(name.to_string()) {
  }

  ResourceTablePackage() = default;
  ResourceTableType* FindType(ResourceType type) const;
  ResourceTableType* FindOrCreateType(ResourceType type);

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
};

struct ResourceTableEntryView {
  std::string name;
  std::optional<uint16_t> id;
  Visibility visibility;
  std::optional<AllowNew> allow_new;
  std::optional<OverlayableItem> overlayable_item;
  std::optional<StagedId> staged_id;
  std::vector<const ResourceConfigValue*> values;

  const ResourceConfigValue* FindValue(const android::ConfigDescription& config,
                                       android::StringPiece product = {}) const;
};

struct ResourceTableTypeView {
  ResourceType type;
  std::optional<uint8_t> id;
  Visibility::Level visibility_level = Visibility::Level::kUndefined;

  // Entries sorted in ascending entry id order. If ids have not been assigned, the entries are
  // sorted lexicographically.
  std::vector<ResourceTableEntryView> entries;
};

struct ResourceTablePackageView {
  std::string name;
  std::optional<uint8_t> id;
  // Types sorted in ascending type id order. If ids have not been assigned, the types are sorted by
  // their declaration order in the ResourceType enum.
  std::vector<ResourceTableTypeView> types;
};

struct ResourceTableViewOptions {
  bool create_alias_entries = false;
};

struct ResourceTableView {
  // Packages sorted in ascending package id order. If ids have not been assigned, the packages are
  // sorted lexicographically.
  std::vector<ResourceTablePackageView> packages;
};

enum class OnIdConflict {
  // If the resource entry already exists but has a different resource id, the resource value will
  // not be added to the table.
  ERROR,

  // If the resource entry already exists but has a different resource id, create a new resource
  // with this resource name and id combination.
  CREATE_ENTRY,
};

struct NewResource {
  ResourceName name;
  std::unique_ptr<Value> value;
  android::ConfigDescription config;
  std::string product;
  std::optional<std::pair<ResourceId, OnIdConflict>> id;
  std::optional<Visibility> visibility;
  std::optional<OverlayableItem> overlayable;
  std::optional<AllowNew> allow_new;
  std::optional<StagedId> staged_id;
  bool allow_mangled = false;
};

struct NewResourceBuilder {
  explicit NewResourceBuilder(const ResourceNameRef& name);
  explicit NewResourceBuilder(const std::string& name);
  NewResourceBuilder& SetValue(std::unique_ptr<Value> value, android::ConfigDescription config = {},
                               std::string product = {});
  NewResourceBuilder& SetId(ResourceId id, OnIdConflict on_conflict = OnIdConflict::ERROR);
  NewResourceBuilder& SetVisibility(Visibility id);
  NewResourceBuilder& SetOverlayable(OverlayableItem overlayable);
  NewResourceBuilder& SetAllowNew(AllowNew allow_new);
  NewResourceBuilder& SetStagedId(StagedId id);
  NewResourceBuilder& SetAllowMangled(bool allow_mangled);
  NewResource Build();

 private:
  NewResource res_;
};

// The container and index for all resources defined for an app.
class ResourceTable {
 public:
  enum class Validation {
    kEnabled,
    kDisabled,
  };

  enum class CollisionResult { kKeepBoth, kKeepOriginal, kConflict, kTakeNew };

  ResourceTable() = default;
  explicit ResourceTable(Validation validation);

  bool AddResource(NewResource&& res, IDiagnostics* diag);

  // Retrieves a sorted a view of the packages, types, and entries sorted in ascending resource id
  // order.
  ResourceTableView GetPartitionedView(const ResourceTableViewOptions& options = {}) const;

  struct SearchResult {
    ResourceTablePackage* package;
    ResourceTableType* type;
    ResourceEntry* entry;
  };

  std::optional<SearchResult> FindResource(const ResourceNameRef& name) const;
  std::optional<SearchResult> FindResource(const ResourceNameRef& name, ResourceId id) const;
  bool RemoveResource(const ResourceNameRef& name, ResourceId id) const;

  // Returns the package struct with the given name, or nullptr if such a package does not
  // exist. The empty string is a valid package and typically is used to represent the
  // 'current' package before it is known to the ResourceTable.
  ResourceTablePackage* FindPackage(const android::StringPiece& name) const;
  ResourceTablePackage* FindOrCreatePackage(const android::StringPiece& name);

  std::unique_ptr<ResourceTable> Clone() const;

  // When a collision of resources occurs, this method decides which value to keep.
  static CollisionResult ResolveValueCollision(Value* existing, Value* incoming);

  // The string pool used by this resource table. Values that reference strings must use
  // this pool to create their strings.
  // NOTE: `string_pool` must come before `packages` so that it is destroyed after.
  // When `string_pool` references are destroyed (as they will be when `packages` is destroyed),
  // they decrement a refCount, which would cause invalid memory access if the pool was already
  // destroyed.
  StringPool string_pool;

  // The list of packages in this table, sorted alphabetically by package name and increasing
  // package ID (missing ID being the lowest).
  std::vector<std::unique_ptr<ResourceTablePackage>> packages;

  // Set of dynamic packages that this table may reference. Their package names get encoded
  // into the resources.arsc along with their compile-time assigned IDs.
  std::map<size_t, std::string> included_packages_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceTable);

  Validation validation_ = Validation::kEnabled;
};

}  // namespace aapt

#endif  // AAPT_RESOURCE_TABLE_H
