/*
 * 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_TEST_BUILDERS_H
#define AAPT_TEST_BUILDERS_H

#include <memory>

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

#include "Resource.h"
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "configuration/ConfigurationParser.h"
#include "configuration/ConfigurationParser.internal.h"
#include "process/IResourceTableConsumer.h"
#include "test/Common.h"
#include "xml/XmlDom.h"

namespace aapt {
namespace test {

class ResourceTableBuilder {
 public:
  ResourceTableBuilder() = default;

  ResourceTableBuilder& AddSimple(android::StringPiece name, const ResourceId& id = {});
  ResourceTableBuilder& AddSimple(android::StringPiece name,
                                  const android::ConfigDescription& config,
                                  const ResourceId& id = {});
  ResourceTableBuilder& AddReference(android::StringPiece name, android::StringPiece ref);
  ResourceTableBuilder& AddReference(android::StringPiece name, const ResourceId& id,
                                     android::StringPiece ref);
  ResourceTableBuilder& AddString(android::StringPiece name, android::StringPiece str);
  ResourceTableBuilder& AddString(android::StringPiece name, const ResourceId& id,
                                  android::StringPiece str);
  ResourceTableBuilder& AddString(android::StringPiece name, const ResourceId& id,
                                  const android::ConfigDescription& config,
                                  android::StringPiece str);
  ResourceTableBuilder& AddFileReference(android::StringPiece name, android::StringPiece path,
                                         io::IFile* file = nullptr);
  ResourceTableBuilder& AddFileReference(android::StringPiece name, const ResourceId& id,
                                         android::StringPiece path, io::IFile* file = nullptr);
  ResourceTableBuilder& AddFileReference(android::StringPiece name, android::StringPiece path,
                                         const android::ConfigDescription& config,
                                         io::IFile* file = nullptr);
  ResourceTableBuilder& AddValue(android::StringPiece name, std::unique_ptr<Value> value);
  ResourceTableBuilder& AddValue(android::StringPiece name, const ResourceId& id,
                                 std::unique_ptr<Value> value);
  ResourceTableBuilder& AddValue(android::StringPiece name,
                                 const android::ConfigDescription& config, const ResourceId& id,
                                 std::unique_ptr<Value> value);
  ResourceTableBuilder& SetSymbolState(android::StringPiece name, const ResourceId& id,
                                       Visibility::Level level, bool allow_new = false);
  ResourceTableBuilder& SetOverlayable(android::StringPiece name,
                                       const OverlayableItem& overlayable);
  ResourceTableBuilder& Add(NewResource&& res);

  android::StringPool* string_pool();
  std::unique_ptr<ResourceTable> Build();

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceTableBuilder);

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

std::unique_ptr<Reference> BuildReference(android::StringPiece ref,
                                          const std::optional<ResourceId>& id = {});
std::unique_ptr<BinaryPrimitive> BuildPrimitive(uint8_t type, uint32_t data);

template <typename T>
class ValueBuilder {
 public:
  template <typename... Args>
  explicit ValueBuilder(Args&&... args) : value_(new T{std::forward<Args>(args)...}) {
  }

  template <typename... Args>
  ValueBuilder& SetSource(Args&&... args) {
    value_->SetSource(android::Source{std::forward<Args>(args)...});
    return *this;
  }

  ValueBuilder& SetComment(android::StringPiece str) {
    value_->SetComment(str);
    return *this;
  }

  std::unique_ptr<Value> Build() {
    return std::move(value_);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ValueBuilder);

  std::unique_ptr<Value> value_;
};

class AttributeBuilder {
 public:
  AttributeBuilder();
  AttributeBuilder& SetTypeMask(uint32_t typeMask);
  AttributeBuilder& SetWeak(bool weak);
  AttributeBuilder& SetComment(android::StringPiece comment);
  AttributeBuilder& AddItem(android::StringPiece name, uint32_t value);
  AttributeBuilder& AddItemWithComment(android::StringPiece name, uint32_t value,
                                       android::StringPiece comment);
  std::unique_ptr<Attribute> Build();

 private:
  DISALLOW_COPY_AND_ASSIGN(AttributeBuilder);

  std::unique_ptr<Attribute> attr_;
};

class StyleBuilder {
 public:
  StyleBuilder() = default;
  StyleBuilder& SetParent(android::StringPiece str);
  StyleBuilder& AddItem(android::StringPiece str, std::unique_ptr<Item> value);
  StyleBuilder& AddItem(android::StringPiece str, const ResourceId& id,
                        std::unique_ptr<Item> value);
  std::unique_ptr<Style> Build();

 private:
  DISALLOW_COPY_AND_ASSIGN(StyleBuilder);

  std::unique_ptr<Style> style_ = util::make_unique<Style>();
};

class StyleableBuilder {
 public:
  StyleableBuilder() = default;
  StyleableBuilder& AddItem(android::StringPiece str, const std::optional<ResourceId>& id = {});
  std::unique_ptr<Styleable> Build();

 private:
  DISALLOW_COPY_AND_ASSIGN(StyleableBuilder);

  std::unique_ptr<Styleable> styleable_ = util::make_unique<Styleable>();
};

std::unique_ptr<xml::XmlResource> BuildXmlDom(android::StringPiece str);
std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(IAaptContext* context,
                                                            android::StringPiece str);

class ArtifactBuilder {
 public:
  ArtifactBuilder() = default;

  ArtifactBuilder& SetName(const std::string& name);
  ArtifactBuilder& SetVersion(int version);
  ArtifactBuilder& AddAbi(configuration::Abi abi);
  ArtifactBuilder& AddDensity(const android::ConfigDescription& density);
  ArtifactBuilder& AddLocale(const android::ConfigDescription& locale);
  ArtifactBuilder& SetAndroidSdk(int min_sdk);
  configuration::OutputArtifact Build();

 private:
  DISALLOW_COPY_AND_ASSIGN(ArtifactBuilder);

  configuration::OutputArtifact artifact_;
};

class PostProcessingConfigurationBuilder {
 public:
  PostProcessingConfigurationBuilder() = default;

  PostProcessingConfigurationBuilder& AddAbiGroup(const std::string& label,
                                                  std::vector<configuration::Abi> abis = {});
  PostProcessingConfigurationBuilder& AddDensityGroup(const std::string& label,
                                                      std::vector<std::string> densities = {});
  PostProcessingConfigurationBuilder& AddLocaleGroup(const std::string& label,
                                                     std::vector<std::string> locales = {});
  PostProcessingConfigurationBuilder& AddDeviceFeatureGroup(const std::string& label);
  PostProcessingConfigurationBuilder& AddGlTextureGroup(const std::string& label);
  PostProcessingConfigurationBuilder& AddAndroidSdk(std::string label, int min_sdk);
  PostProcessingConfigurationBuilder& AddArtifact(configuration::ConfiguredArtifact artrifact);

  configuration::PostProcessingConfiguration Build();

 private:
  template <typename T>
  inline PostProcessingConfigurationBuilder& AddGroup(const std::string& label,
                                                      configuration::Group<T>* group,
                                                      std::vector<T> to_add = {}) {
    auto& values = GetOrCreateGroup(label, group);
    values.insert(std::begin(values), std::begin(to_add), std::end(to_add));
    return *this;
  }

  configuration::PostProcessingConfiguration config_;
};

class ConfigDescriptionBuilder {
 public:
  ConfigDescriptionBuilder() = default;

  ConfigDescriptionBuilder& setMcc(uint16_t mcc) {
    config_.mcc = mcc;
    return *this;
  }
  ConfigDescriptionBuilder& setMnc(uint16_t mnc) {
    config_.mnc = mnc;
    return *this;
  }
  ConfigDescriptionBuilder& setLanguage(uint16_t language) {
    config_.language[0] = language >> 8;
    config_.language[1] = language & 0xff;
    return *this;
  }
  ConfigDescriptionBuilder& setCountry(uint16_t country) {
    config_.country[0] = country >> 8;
    config_.country[1] = country & 0xff;
    return *this;
  }
  ConfigDescriptionBuilder& setOrientation(uint8_t orientation) {
    config_.orientation = orientation;
    return *this;
  }
  ConfigDescriptionBuilder& setTouchscreen(uint8_t touchscreen) {
    config_.touchscreen = touchscreen;
    return *this;
  }
  ConfigDescriptionBuilder& setDensity(uint16_t density) {
    config_.density = density;
    return *this;
  }
  ConfigDescriptionBuilder& setKeyboard(uint8_t keyboard) {
    config_.keyboard = keyboard;
    return *this;
  }
  ConfigDescriptionBuilder& setNavigation(uint8_t navigation) {
    config_.navigation = navigation;
    return *this;
  }
  ConfigDescriptionBuilder& setInputFlags(uint8_t inputFlags) {
    config_.inputFlags = inputFlags;
    return *this;
  }
  ConfigDescriptionBuilder& setInputPad0(uint8_t inputPad0) {
    config_.inputFieldPad0 = inputPad0;
    return *this;
  }
  ConfigDescriptionBuilder& setGrammaticalInflection(uint8_t value) {
    config_.grammaticalInflection = value;
    return *this;
  }
  ConfigDescriptionBuilder& setScreenWidth(uint16_t screenWidth) {
    config_.screenWidth = screenWidth;
    return *this;
  }
  ConfigDescriptionBuilder& setScreenHeight(uint16_t screenHeight) {
    config_.screenHeight = screenHeight;
    return *this;
  }
  ConfigDescriptionBuilder& setSdkVersion(uint16_t sdkVersion) {
    config_.sdkVersion = sdkVersion;
    return *this;
  }
  ConfigDescriptionBuilder& setMinorVersion(uint16_t minorVersion) {
    config_.minorVersion = minorVersion;
    return *this;
  }
  ConfigDescriptionBuilder& setScreenLayout(uint8_t screenLayout) {
    config_.screenLayout = screenLayout;
    return *this;
  }
  ConfigDescriptionBuilder& setUiMode(uint8_t uiMode) {
    config_.uiMode = uiMode;
    return *this;
  }
  ConfigDescriptionBuilder& setSmallestScreenWidthDp(uint16_t smallestScreenWidthDp) {
    config_.smallestScreenWidthDp = smallestScreenWidthDp;
    return *this;
  }
  ConfigDescriptionBuilder& setScreenWidthDp(uint16_t screenWidthDp) {
    config_.screenWidthDp = screenWidthDp;
    return *this;
  }
  ConfigDescriptionBuilder& setScreenHeightDp(uint16_t screenHeightDp) {
    config_.screenHeightDp = screenHeightDp;
    return *this;
  }
  ConfigDescriptionBuilder& setScreenLayout2(uint8_t screenLayout2) {
    config_.screenLayout2 = screenLayout2;
    return *this;
  }
  ConfigDescriptionBuilder& setColorMode(uint8_t colorMode) {
    config_.colorMode = colorMode;
    return *this;
  }
  ConfigDescriptionBuilder& setScreenConfigPad2(uint16_t screenConfigPad2) {
    config_.screenConfigPad2 = screenConfigPad2;
    return *this;
  }
  android::ConfigDescription Build() {
    return config_;
  }

 private:
  android::ConfigDescription config_;
};

}  // namespace test
}  // namespace aapt

#endif /* AAPT_TEST_BUILDERS_H */
