/*
 * 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_PROGUARD_RULES_H
#define AAPT_PROGUARD_RULES_H

#include <map>
#include <ostream>
#include <set>
#include <string>

#include "androidfw/StringPiece.h"

#include "Resource.h"
#include "ResourceTable.h"
#include "Source.h"
#include "ValueVisitor.h"
#include "io/Io.h"
#include "process/IResourceTableConsumer.h"
#include "xml/XmlDom.h"

namespace aapt {
namespace proguard {

struct UsageLocation {
  ResourceName name;
  Source source;
};

struct NameAndSignature {
  std::string name;
  std::string signature;
};

class KeepSet {
 public:
  KeepSet() = default;

  KeepSet(bool conditional_keep_rules) : conditional_keep_rules_(conditional_keep_rules) {
  }

  inline void AddManifestClass(const UsageLocation& file, const std::string& class_name) {
    manifest_class_set_[class_name].insert(file);
  }

  inline void AddConditionalClass(const UsageLocation& file,
                                  const NameAndSignature& class_and_signature) {
    conditional_class_set_[class_and_signature].insert(file);
  }

  inline void AddMethod(const UsageLocation& file, const NameAndSignature& name_and_signature) {
    method_set_[name_and_signature].insert(file);
  }

  inline void AddReference(const UsageLocation& file, const ResourceName& resource_name) {
    reference_set_[resource_name].insert(file);
  }

 private:
  friend void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out);

  friend bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set,
                               std::set<UsageLocation>* locations);

  bool conditional_keep_rules_ = false;
  std::map<std::string, std::set<UsageLocation>> manifest_class_set_;
  std::map<NameAndSignature, std::set<UsageLocation>> method_set_;
  std::map<NameAndSignature, std::set<UsageLocation>> conditional_class_set_;
  std::map<ResourceName, std::set<UsageLocation>> reference_set_;
};

bool CollectProguardRulesForManifest(xml::XmlResource* res, KeepSet* keep_set,
                                     bool main_dex_only = false);

bool CollectProguardRules(IAaptContext* context, xml::XmlResource* res, KeepSet* keep_set);

bool CollectResourceReferences(IAaptContext* context, ResourceTable* table, KeepSet* keep_set);

void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out);

bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set,
                      std::set<UsageLocation>* locations);

//
// UsageLocation implementation.
//

inline bool operator==(const UsageLocation& lhs, const UsageLocation& rhs) {
  return lhs.name == rhs.name;
}

inline int operator<(const UsageLocation& lhs, const UsageLocation& rhs) {
  return lhs.name.compare(rhs.name);
}

//
// NameAndSignature implementation.
//

inline bool operator<(const NameAndSignature& lhs, const NameAndSignature& rhs) {
  if (lhs.name < rhs.name) {
    return true;
  }
  if (lhs.name == rhs.name) {
    return lhs.signature < rhs.signature;
  }
  return false;
}

}  // namespace proguard
}  // namespace aapt

#endif  // AAPT_PROGUARD_RULES_H
