/*
 * 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 "proto/ProtoSerialize.h"

#include "android-base/logging.h"
#include "androidfw/ResourceTypes.h"

#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ValueVisitor.h"
#include "proto/ProtoHelpers.h"

namespace aapt {

namespace {

class ReferenceIdToNameVisitor : public ValueVisitor {
 public:
  using ValueVisitor::Visit;

  explicit ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceNameRef>* mapping)
      : mapping_(mapping) {
    CHECK(mapping_ != nullptr);
  }

  void Visit(Reference* reference) override {
    if (!reference->id || !reference->id.value().is_valid()) {
      return;
    }

    ResourceId id = reference->id.value();
    auto cache_iter = mapping_->find(id);
    if (cache_iter != mapping_->end()) {
      reference->name = cache_iter->second.ToResourceName();
    }
  }

 private:
  const std::map<ResourceId, ResourceNameRef>* mapping_;
};

class PackagePbDeserializer {
 public:
  PackagePbDeserializer(const android::ResStringPool* valuePool,
                        const android::ResStringPool* sourcePool,
                        const android::ResStringPool* symbolPool,
                        const Source& source, IDiagnostics* diag)
      : value_pool_(valuePool),
        source_pool_(sourcePool),
        symbol_pool_(symbolPool),
        source_(source),
        diag_(diag) {}

 public:
  bool DeserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) {
    Maybe<uint8_t> id;
    if (pbPackage.has_package_id()) {
      id = static_cast<uint8_t>(pbPackage.package_id());
    }

    std::map<ResourceId, ResourceNameRef> idIndex;

    ResourceTablePackage* pkg = table->CreatePackage(pbPackage.package_name(), id);
    for (const pb::Type& pbType : pbPackage.types()) {
      const ResourceType* resType = ParseResourceType(pbType.name());
      if (!resType) {
        diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name() << "'");
        return {};
      }

      ResourceTableType* type = pkg->FindOrCreateType(*resType);

      for (const pb::Entry& pbEntry : pbType.entries()) {
        ResourceEntry* entry = type->FindOrCreateEntry(pbEntry.name());

        // Deserialize the symbol status (public/private with source and
        // comments).
        if (pbEntry.has_symbol_status()) {
          const pb::SymbolStatus& pbStatus = pbEntry.symbol_status();
          if (pbStatus.has_source()) {
            DeserializeSourceFromPb(pbStatus.source(), *source_pool_, &entry->symbol_status.source);
          }

          if (pbStatus.has_comment()) {
            entry->symbol_status.comment = pbStatus.comment();
          }

          entry->symbol_status.allow_new = pbStatus.allow_new();

          SymbolState visibility = DeserializeVisibilityFromPb(pbStatus.visibility());
          entry->symbol_status.state = visibility;

          if (visibility == SymbolState::kPublic) {
            // This is a public symbol, we must encode the ID now if there is one.
            if (pbEntry.has_id()) {
              entry->id = static_cast<uint16_t>(pbEntry.id());
            }

            if (type->symbol_status.state != SymbolState::kPublic) {
              // If the type has not been made public, do so now.
              type->symbol_status.state = SymbolState::kPublic;
              if (pbType.has_id()) {
                type->id = static_cast<uint8_t>(pbType.id());
              }
            }
          } else if (visibility == SymbolState::kPrivate) {
            if (type->symbol_status.state == SymbolState::kUndefined) {
              type->symbol_status.state = SymbolState::kPrivate;
            }
          }
        }

        ResourceId resId(pbPackage.package_id(), pbType.id(), pbEntry.id());
        if (resId.is_valid()) {
          idIndex[resId] = ResourceNameRef(pkg->name, type->type, entry->name);
        }

        for (const pb::ConfigValue& pbConfigValue : pbEntry.config_values()) {
          const pb::ConfigDescription& pbConfig = pbConfigValue.config();

          ConfigDescription config;
          if (!DeserializeConfigDescriptionFromPb(pbConfig, &config)) {
            diag_->Error(DiagMessage(source_) << "invalid configuration");
            return {};
          }

          ResourceConfigValue* configValue = entry->FindOrCreateValue(config, pbConfig.product());
          if (configValue->value) {
            // Duplicate config.
            diag_->Error(DiagMessage(source_) << "duplicate configuration");
            return {};
          }

          configValue->value =
              DeserializeValueFromPb(pbConfigValue.value(), config, &table->string_pool);
          if (!configValue->value) {
            return {};
          }
        }
      }
    }

    ReferenceIdToNameVisitor visitor(&idIndex);
    VisitAllValuesInPackage(pkg, &visitor);
    return true;
  }

 private:
  std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
                                              const ConfigDescription& config,
                                              StringPool* pool) {
    if (pb_item.has_ref()) {
      const pb::Reference& pb_ref = pb_item.ref();
      std::unique_ptr<Reference> ref = util::make_unique<Reference>();
      if (!DeserializeReferenceFromPb(pb_ref, ref.get())) {
        return {};
      }
      return std::move(ref);

    } else if (pb_item.has_prim()) {
      const pb::Primitive& pb_prim = pb_item.prim();
      android::Res_value prim = {};
      prim.dataType = static_cast<uint8_t>(pb_prim.type());
      prim.data = pb_prim.data();
      return util::make_unique<BinaryPrimitive>(prim);

    } else if (pb_item.has_id()) {
      return util::make_unique<Id>();

    } else if (pb_item.has_str()) {
      const uint32_t idx = pb_item.str().idx();
      const std::string str = util::GetString(*value_pool_, idx);

      const android::ResStringPool_span* spans = value_pool_->styleAt(idx);
      if (spans && spans->name.index != android::ResStringPool_span::END) {
        StyleString style_str = {str};
        while (spans->name.index != android::ResStringPool_span::END) {
          style_str.spans.push_back(
              Span{util::GetString(*value_pool_, spans->name.index),
                   spans->firstChar, spans->lastChar});
          spans++;
        }
        return util::make_unique<StyledString>(pool->MakeRef(
            style_str, StringPool::Context(StringPool::Context::kNormalPriority, config)));
      }
      return util::make_unique<String>(
          pool->MakeRef(str, StringPool::Context(config)));

    } else if (pb_item.has_raw_str()) {
      const uint32_t idx = pb_item.raw_str().idx();
      const std::string str = util::GetString(*value_pool_, idx);
      return util::make_unique<RawString>(
          pool->MakeRef(str, StringPool::Context(config)));

    } else if (pb_item.has_file()) {
      const uint32_t idx = pb_item.file().path_idx();
      const std::string str = util::GetString(*value_pool_, idx);
      return util::make_unique<FileReference>(pool->MakeRef(
          str,
          StringPool::Context(StringPool::Context::kHighPriority, config)));

    } else {
      diag_->Error(DiagMessage(source_) << "unknown item");
    }
    return {};
  }

  std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
                                                const ConfigDescription& config,
                                                StringPool* pool) {
    const bool is_weak = pb_value.has_weak() ? pb_value.weak() : false;

    std::unique_ptr<Value> value;
    if (pb_value.has_item()) {
      value = DeserializeItemFromPb(pb_value.item(), config, pool);
      if (!value) {
        return {};
      }

    } else if (pb_value.has_compound_value()) {
      const pb::CompoundValue& pb_compound_value = pb_value.compound_value();
      if (pb_compound_value.has_attr()) {
        const pb::Attribute& pb_attr = pb_compound_value.attr();
        std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(is_weak);
        attr->type_mask = pb_attr.format_flags();
        attr->min_int = pb_attr.min_int();
        attr->max_int = pb_attr.max_int();
        for (const pb::Attribute_Symbol& pb_symbol : pb_attr.symbols()) {
          Attribute::Symbol symbol;
          DeserializeItemCommon(pb_symbol, &symbol.symbol);
          if (!DeserializeReferenceFromPb(pb_symbol.name(), &symbol.symbol)) {
            return {};
          }
          symbol.value = pb_symbol.value();
          attr->symbols.push_back(std::move(symbol));
        }
        value = std::move(attr);

      } else if (pb_compound_value.has_style()) {
        const pb::Style& pb_style = pb_compound_value.style();
        std::unique_ptr<Style> style = util::make_unique<Style>();
        if (pb_style.has_parent()) {
          style->parent = Reference();
          if (!DeserializeReferenceFromPb(pb_style.parent(),
                                          &style->parent.value())) {
            return {};
          }

          if (pb_style.has_parent_source()) {
            Source parent_source;
            DeserializeSourceFromPb(pb_style.parent_source(), *source_pool_,
                                    &parent_source);
            style->parent.value().SetSource(std::move(parent_source));
          }
        }

        for (const pb::Style_Entry& pb_entry : pb_style.entries()) {
          Style::Entry entry;
          DeserializeItemCommon(pb_entry, &entry.key);
          if (!DeserializeReferenceFromPb(pb_entry.key(), &entry.key)) {
            return {};
          }

          entry.value = DeserializeItemFromPb(pb_entry.item(), config, pool);
          if (!entry.value) {
            return {};
          }

          DeserializeItemCommon(pb_entry, entry.value.get());
          style->entries.push_back(std::move(entry));
        }
        value = std::move(style);

      } else if (pb_compound_value.has_styleable()) {
        const pb::Styleable& pb_styleable = pb_compound_value.styleable();
        std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
        for (const pb::Styleable_Entry& pb_entry : pb_styleable.entries()) {
          Reference attr_ref;
          DeserializeItemCommon(pb_entry, &attr_ref);
          DeserializeReferenceFromPb(pb_entry.attr(), &attr_ref);
          styleable->entries.push_back(std::move(attr_ref));
        }
        value = std::move(styleable);

      } else if (pb_compound_value.has_array()) {
        const pb::Array& pb_array = pb_compound_value.array();
        std::unique_ptr<Array> array = util::make_unique<Array>();
        for (const pb::Array_Entry& pb_entry : pb_array.entries()) {
          std::unique_ptr<Item> item =
              DeserializeItemFromPb(pb_entry.item(), config, pool);
          if (!item) {
            return {};
          }

          DeserializeItemCommon(pb_entry, item.get());
          array->items.push_back(std::move(item));
        }
        value = std::move(array);

      } else if (pb_compound_value.has_plural()) {
        const pb::Plural& pb_plural = pb_compound_value.plural();
        std::unique_ptr<Plural> plural = util::make_unique<Plural>();
        for (const pb::Plural_Entry& pb_entry : pb_plural.entries()) {
          size_t pluralIdx = DeserializePluralEnumFromPb(pb_entry.arity());
          plural->values[pluralIdx] =
              DeserializeItemFromPb(pb_entry.item(), config, pool);
          if (!plural->values[pluralIdx]) {
            return {};
          }

          DeserializeItemCommon(pb_entry, plural->values[pluralIdx].get());
        }
        value = std::move(plural);

      } else {
        diag_->Error(DiagMessage(source_) << "unknown compound value");
        return {};
      }
    } else {
      diag_->Error(DiagMessage(source_) << "unknown value");
      return {};
    }

    CHECK(value) << "forgot to set value";

    value->SetWeak(is_weak);
    DeserializeItemCommon(pb_value, value.get());
    return value;
  }

  bool DeserializeReferenceFromPb(const pb::Reference& pb_ref, Reference* out_ref) {
    out_ref->reference_type = DeserializeReferenceTypeFromPb(pb_ref.type());
    out_ref->private_reference = pb_ref.private_();

    if (pb_ref.has_id()) {
      out_ref->id = ResourceId(pb_ref.id());
    }

    if (pb_ref.has_symbol_idx()) {
      const std::string str_symbol = util::GetString(*symbol_pool_, pb_ref.symbol_idx());
      ResourceNameRef name_ref;
      if (!ResourceUtils::ParseResourceName(str_symbol, &name_ref, nullptr)) {
        diag_->Error(DiagMessage(source_) << "invalid reference name '" << str_symbol << "'");
        return false;
      }

      out_ref->name = name_ref.ToResourceName();
    }
    return true;
  }

  template <typename T>
  void DeserializeItemCommon(const T& pb_item, Value* out_value) {
    if (pb_item.has_source()) {
      Source source;
      DeserializeSourceFromPb(pb_item.source(), *source_pool_, &source);
      out_value->SetSource(std::move(source));
    }

    if (pb_item.has_comment()) {
      out_value->SetComment(pb_item.comment());
    }
  }

 private:
  const android::ResStringPool* value_pool_;
  const android::ResStringPool* source_pool_;
  const android::ResStringPool* symbol_pool_;
  const Source source_;
  IDiagnostics* diag_;
};

}  // namespace

std::unique_ptr<ResourceTable> DeserializeTableFromPb(
    const pb::ResourceTable& pb_table, const Source& source,
    IDiagnostics* diag) {
  // We import the android namespace because on Windows NO_ERROR is a macro, not
  // an enum, which
  // causes errors when qualifying it with android::
  using namespace android;

  std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();

  if (!pb_table.has_string_pool()) {
    diag->Error(DiagMessage(source) << "no string pool found");
    return {};
  }

  ResStringPool value_pool;
  status_t result = value_pool.setTo(pb_table.string_pool().data().data(),
                                     pb_table.string_pool().data().size());
  if (result != NO_ERROR) {
    diag->Error(DiagMessage(source) << "invalid string pool");
    return {};
  }

  ResStringPool source_pool;
  if (pb_table.has_source_pool()) {
    result = source_pool.setTo(pb_table.source_pool().data().data(),
                               pb_table.source_pool().data().size());
    if (result != NO_ERROR) {
      diag->Error(DiagMessage(source) << "invalid source pool");
      return {};
    }
  }

  ResStringPool symbol_pool;
  if (pb_table.has_symbol_pool()) {
    result = symbol_pool.setTo(pb_table.symbol_pool().data().data(),
                               pb_table.symbol_pool().data().size());
    if (result != NO_ERROR) {
      diag->Error(DiagMessage(source) << "invalid symbol pool");
      return {};
    }
  }

  PackagePbDeserializer package_pb_deserializer(&value_pool, &source_pool,
                                                &symbol_pool, source, diag);
  for (const pb::Package& pb_package : pb_table.packages()) {
    if (!package_pb_deserializer.DeserializeFromPb(pb_package, table.get())) {
      return {};
    }
  }
  return table;
}

std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb(
    const pb::CompiledFile& pb_file, const Source& source, IDiagnostics* diag) {
  std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>();

  ResourceNameRef name_ref;

  // Need to create an lvalue here so that nameRef can point to something real.
  if (!ResourceUtils::ParseResourceName(pb_file.resource_name(), &name_ref)) {
    diag->Error(DiagMessage(source)
                << "invalid resource name in compiled file header: "
                << pb_file.resource_name());
    return {};
  }
  file->name = name_ref.ToResourceName();
  file->source.path = pb_file.source_path();
  DeserializeConfigDescriptionFromPb(pb_file.config(), &file->config);

  for (const pb::CompiledFile_Symbol& pb_symbol : pb_file.exported_symbols()) {
    // Need to create an lvalue here so that nameRef can point to something
    // real.
    if (!ResourceUtils::ParseResourceName(pb_symbol.resource_name(),
                                          &name_ref)) {
      diag->Error(DiagMessage(source)
                  << "invalid resource name for exported symbol in "
                     "compiled file header: "
                  << pb_file.resource_name());
      return {};
    }
    file->exported_symbols.push_back(
        SourcedResourceName{name_ref.ToResourceName(), pb_symbol.line_no()});
  }
  return file;
}

}  // namespace aapt
