/*
 * 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_JAVA_CLASSDEFINITION_H
#define AAPT_JAVA_CLASSDEFINITION_H

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

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

#include "Resource.h"
#include "java/AnnotationProcessor.h"
#include "text/Printer.h"
#include "util/Util.h"

namespace aapt {

// The number of attributes to emit per line in a Styleable array.
constexpr static size_t kAttribsPerLine = 4;
constexpr static const char* kIndent = "  ";

class ClassMember {
 public:
  virtual ~ClassMember() = default;

  AnnotationProcessor* GetCommentBuilder() {
    return &processor_;
  }

  virtual bool empty() const = 0;

  virtual const std::string& GetName() const = 0;

  // Writes the class member to the Printer. Subclasses should derive this method
  // to write their own data. Call this base method from the subclass to write out
  // this member's comments/annotations.
  virtual void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) const;

 private:
  AnnotationProcessor processor_;
};

template <typename T>
class PrimitiveMember : public ClassMember {
 public:
  PrimitiveMember(android::StringPiece name, const T& val, bool staged_api = false)
      : name_(name), val_(val), staged_api_(staged_api) {
  }

  bool empty() const override {
    return false;
  }

  const std::string& GetName() const override {
    return name_;
  }

  void Print(bool final, text::Printer* printer,
             bool strip_api_annotations = false) const override {
    using std::to_string;

    ClassMember::Print(final, printer, strip_api_annotations);

    printer->Print("public static ");
    if (final) {
      printer->Print("final ");
    }
    printer->Print("int ").Print(name_);
    if (staged_api_) {
      // Prevent references to staged apis from being inline by setting their value out-of-line.
      printer->Print("; static { ").Print(name_);
    }
    printer->Print("=").Print(to_string(val_)).Print(";");
    if (staged_api_) {
      printer->Print(" }");
    }
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(PrimitiveMember);

  std::string name_;
  T val_;
  bool staged_api_;
};

// Specialization for strings so they get the right type and are quoted with "".
template <>
class PrimitiveMember<std::string> : public ClassMember {
 public:
  PrimitiveMember(android::StringPiece name, const std::string& val, bool staged_api = false)
      : name_(name), val_(val) {
  }

  bool empty() const override {
    return false;
  }

  const std::string& GetName() const override {
    return name_;
  }

  void Print(bool final, text::Printer* printer, bool strip_api_annotations = false)
      const override {
    ClassMember::Print(final, printer, strip_api_annotations);

    printer->Print("public static ");
    if (final) {
      printer->Print("final ");
    }
    printer->Print("String ").Print(name_).Print("=\"").Print(val_).Print("\";");
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(PrimitiveMember);

  std::string name_;
  std::string val_;
};

using IntMember = PrimitiveMember<uint32_t>;
using ResourceMember = PrimitiveMember<ResourceId>;
using StringMember = PrimitiveMember<std::string>;

template <typename T, typename StringConverter>
class PrimitiveArrayMember : public ClassMember {
 public:
  explicit PrimitiveArrayMember(android::StringPiece name) : name_(name) {
  }

  void AddElement(const T& val) {
    elements_.emplace_back(val);
  }

  bool empty() const override {
    return false;
  }

  const std::string& GetName() const override {
    return name_;
  }

  void Print(bool final, text::Printer* printer, bool strip_api_annotations = false)
      const override {
    ClassMember::Print(final, printer, strip_api_annotations);

    printer->Print("public static final int[] ").Print(name_).Print("={");
    printer->Indent();

    const auto begin = elements_.begin();
    const auto end = elements_.end();
    for (auto current = begin; current != end; ++current) {
      if (std::distance(begin, current) % kAttribsPerLine == 0) {
        printer->Println();
      }

      printer->Print(StringConverter::ToString(*current));
      if (std::distance(current, end) > 1) {
        printer->Print(", ");
      }
    }
    printer->Println();
    printer->Undent();
    printer->Print("};");
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(PrimitiveArrayMember);

  std::string name_;
  std::vector<T> elements_;
};

struct FieldReference {
  explicit FieldReference(std::string reference) : ref(std::move(reference)) {
  }
  std::string ref;
};

struct ResourceArrayMemberStringConverter {
  static std::string ToString(const std::variant<ResourceId, FieldReference>& ref) {
    if (auto id = std::get_if<ResourceId>(&ref)) {
      return to_string(*id);
    } else {
      return std::get<FieldReference>(ref).ref;
    }
  }
};

using ResourceArrayMember = PrimitiveArrayMember<std::variant<ResourceId, FieldReference>,
                                                 ResourceArrayMemberStringConverter>;

// Represents a method in a class.
class MethodDefinition : public ClassMember {
 public:
  // Expected method signature example: 'public static void onResourcesLoaded(int p)'.
  explicit MethodDefinition(android::StringPiece signature) : signature_(signature) {
  }

  // Appends a single statement to the method. It should include no newlines or else
  // formatting may be broken.
  void AppendStatement(android::StringPiece statement);

  // Not quite the same as a name, but good enough.
  const std::string& GetName() const override {
    return signature_;
  }

  // Even if the method is empty, we always want to write the method signature.
  bool empty() const override {
    return false;
  }

  void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(MethodDefinition);

  std::string signature_;
  std::vector<std::string> statements_;
};

enum class ClassQualifier { kNone, kStatic };

class ClassDefinition : public ClassMember {
 public:
  static void WriteJavaFile(const ClassDefinition* def, android::StringPiece package, bool final,
                            bool strip_api_annotations, android::OutputStream* out);

  ClassDefinition(android::StringPiece name, ClassQualifier qualifier, bool createIfEmpty)
      : name_(name), qualifier_(qualifier), create_if_empty_(createIfEmpty) {
  }

  enum class Result {
    kAdded,
    kOverridden,
  };

  Result AddMember(std::unique_ptr<ClassMember> member);

  bool empty() const override;

  const std::string& GetName() const override {
    return name_;
  }

  void Print(bool final, text::Printer* printer, bool strip_api_annotations = false) const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(ClassDefinition);

  std::string name_;
  ClassQualifier qualifier_;
  bool create_if_empty_;
  std::vector<std::unique_ptr<ClassMember>> ordered_members_;
  std::unordered_map<android::StringPiece, size_t> indexed_members_;
};

}  // namespace aapt

#endif /* AAPT_JAVA_CLASSDEFINITION_H */
