/*
 * Copyright (C) 2017 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 AAPT2_CONFIGURATION_H
#define AAPT2_CONFIGURATION_H

#include <set>
#include <string>
#include <unordered_map>
#include <vector>

#include "androidfw/ConfigDescription.h"

#include "Diagnostics.h"
#include "util/Maybe.h"

namespace aapt {

namespace configuration {

/** Enumeration of currently supported ABIs. */
enum class Abi {
  kArmeV6,
  kArmV7a,
  kArm64V8a,
  kX86,
  kX86_64,
  kMips,
  kMips64,
  kUniversal
};

/** Helper method to convert an ABI to a string representing the path within the APK. */
const android::StringPiece& AbiToString(Abi abi);

/**
 * Represents an individual locale. When a locale is included, it must be
 * declared from least specific to most specific, as a region does not make
 * sense without a language. If neither the language or region are specified it
 * acts as a special case for catch all. This can allow all locales to be kept,
 * or compressed.
 */
struct Locale {
  /** The ISO<?> standard locale language code. */
  Maybe<std::string> lang;
  /** The ISO<?> standard locale region code. */
  Maybe<std::string> region;

  inline friend bool operator==(const Locale& lhs, const Locale& rhs) {
    return lhs.lang == rhs.lang && lhs.region == rhs.region;
  }
};

// TODO: Encapsulate manifest modifications from the configuration file.
struct AndroidManifest {
  inline friend bool operator==(const AndroidManifest& lhs, const AndroidManifest& rhs) {
    return true;  // nothing to compare yet.
  }
};

struct AndroidSdk {
  std::string label;
  int min_sdk_version;  // min_sdk_version is mandatory if splitting by SDK.
  Maybe<int> target_sdk_version;
  Maybe<int> max_sdk_version;
  Maybe<AndroidManifest> manifest;

  static AndroidSdk ForMinSdk(int min_sdk) {
    AndroidSdk sdk;
    sdk.min_sdk_version = min_sdk;
    return sdk;
  }

  inline friend bool operator==(const AndroidSdk& lhs, const AndroidSdk& rhs) {
    return lhs.min_sdk_version == rhs.min_sdk_version &&
        lhs.target_sdk_version == rhs.target_sdk_version &&
        lhs.max_sdk_version == rhs.max_sdk_version &&
        lhs.manifest == rhs.manifest;
  }
};

// TODO: Make device features more than just an arbitrary string?
using DeviceFeature = std::string;

/** Represents a mapping of texture paths to a GL texture format. */
struct GlTexture {
  std::string name;
  std::vector<std::string> texture_paths;

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

/** An artifact with all the details pulled from the PostProcessingConfiguration. */
struct OutputArtifact {
  std::string name;
  int version;
  std::vector<Abi> abis;
  std::vector<android::ConfigDescription> screen_densities;
  std::vector<android::ConfigDescription> locales;
  Maybe<AndroidSdk> android_sdk;
  std::vector<DeviceFeature> features;
  std::vector<GlTexture> textures;

  inline int GetMinSdk(int default_value = -1) const {
    if (!android_sdk) {
      return default_value;
    }
    return android_sdk.value().min_sdk_version;
  }
};

}  // namespace configuration

// Forward declaration of classes used in the API.
struct IDiagnostics;

/**
 * XML configuration file parser for the split and optimize commands.
 */
class ConfigurationParser {
 public:

  /** Returns a ConfigurationParser for the file located at the provided path. */
  static Maybe<ConfigurationParser> ForPath(const std::string& path);

  /** Returns a ConfigurationParser for the configuration in the provided file contents. */
  static ConfigurationParser ForContents(const std::string& contents, const std::string& path) {
    ConfigurationParser parser{contents, path};
    return parser;
  }

  /** Sets the diagnostics context to use when parsing. */
  ConfigurationParser& WithDiagnostics(IDiagnostics* diagnostics) {
    diag_ = diagnostics;
    return *this;
  }

  /**
   * Parses the configuration file and returns the results. If the configuration could not be parsed
   * the result is empty and any errors will be displayed with the provided diagnostics context.
   */
  Maybe<std::vector<configuration::OutputArtifact>> Parse(const android::StringPiece& apk_path);

 protected:
  /**
   * Instantiates a new ConfigurationParser with the provided configuration file and a no-op
   * diagnostics context. The default diagnostics context can be overridden with a call to
   * WithDiagnostics(IDiagnostics *).
   */
  ConfigurationParser(std::string contents, const std::string& config_path);

  /** Returns the current diagnostics context to any subclasses. */
  IDiagnostics* diagnostics() {
    return diag_;
  }

 private:
  /** The contents of the configuration file to parse. */
  const std::string contents_;
  /** Path to the input configuration. */
  const std::string config_path_;
  /** The diagnostics context to send messages to. */
  IDiagnostics* diag_;
};

}  // namespace aapt

#endif  // AAPT2_CONFIGURATION_H
