/*
 * Copyright (C) 2018 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 "apk_layout_compiler.h"
#include "dex_layout_compiler.h"
#include "java_lang_builder.h"
#include "layout_validation.h"
#include "util.h"

#include "androidfw/ApkAssets.h"
#include "androidfw/AssetManager2.h"
#include "androidfw/ResourceTypes.h"

#include <iostream>
#include <locale>

#include "android-base/stringprintf.h"

namespace startop {

using android::ResXMLParser;
using android::base::StringPrintf;

class ResXmlVisitorAdapter {
 public:
  ResXmlVisitorAdapter(ResXMLParser* parser) : parser_{parser} {}

  template <typename Visitor>
  void Accept(Visitor* visitor) {
    size_t depth{0};
    do {
      switch (parser_->next()) {
        case ResXMLParser::START_DOCUMENT:
          depth++;
          visitor->VisitStartDocument();
          break;
        case ResXMLParser::END_DOCUMENT:
          depth--;
          visitor->VisitEndDocument();
          break;
        case ResXMLParser::START_TAG: {
          depth++;
          size_t name_length = 0;
          const char16_t* name = parser_->getElementName(&name_length);
          visitor->VisitStartTag(std::u16string{name, name_length});
          break;
        }
        case ResXMLParser::END_TAG:
          depth--;
          visitor->VisitEndTag();
          break;
        default:;
      }
    } while (depth > 0 || parser_->getEventType() == ResXMLParser::FIRST_CHUNK_CODE);
  }

 private:
  ResXMLParser* parser_;
};

bool CanCompileLayout(ResXMLParser* parser) {
  ResXmlVisitorAdapter adapter{parser};
  LayoutValidationVisitor visitor;
  adapter.Accept(&visitor);

  return visitor.can_compile();
}

namespace {
void CompileApkAssetsLayouts(const std::unique_ptr<android::ApkAssets>& assets,
                             CompilationTarget target, std::ostream& target_out) {
  android::AssetManager2 resources;
  resources.SetApkAssets({assets.get()});

  std::string package_name;

  // TODO: handle multiple packages better
  bool first = true;
  for (const auto& package : assets->GetLoadedArsc()->GetPackages()) {
    CHECK(first);
    package_name = package->GetPackageName();
    first = false;
  }

  dex::DexBuilder dex_file;
  dex::ClassBuilder compiled_view{
      dex_file.MakeClass(StringPrintf("%s.CompiledView", package_name.c_str()))};
  std::vector<dex::MethodBuilder> methods;

  assets->GetAssetsProvider()->ForEachFile("res/", [&](const android::StringPiece& s,
                                                       android::FileType) {
    if (s == "layout") {
      auto path = StringPrintf("res/%s/", s.to_string().c_str());
      assets->GetAssetsProvider()->ForEachFile(path, [&](const android::StringPiece& layout_file,
                                                         android::FileType) {
        auto layout_path = StringPrintf("%s%s", path.c_str(), layout_file.to_string().c_str());
        android::ApkAssetsCookie cookie = android::kInvalidCookie;
        auto asset = resources.OpenNonAsset(layout_path, android::Asset::ACCESS_RANDOM, &cookie);
        CHECK(asset);
        CHECK(android::kInvalidCookie != cookie);
        const auto dynamic_ref_table = resources.GetDynamicRefTableForCookie(cookie);
        CHECK(nullptr != dynamic_ref_table);
        android::ResXMLTree xml_tree{dynamic_ref_table};
        xml_tree.setTo(asset->getBuffer(/*wordAligned=*/true),
                       asset->getLength(),
                       /*copy_data=*/true);
        android::ResXMLParser parser{xml_tree};
        parser.restart();
        if (CanCompileLayout(&parser)) {
          parser.restart();
          const std::string layout_name = startop::util::FindLayoutNameFromFilename(layout_path);
          ResXmlVisitorAdapter adapter{&parser};
          switch (target) {
            case CompilationTarget::kDex: {
              methods.push_back(compiled_view.CreateMethod(
                  layout_name,
                  dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.View"),
                                 dex::TypeDescriptor::FromClassname("android.content.Context"),
                                 dex::TypeDescriptor::Int()}));
              DexViewBuilder builder(&methods.back());
              builder.Start();
              LayoutCompilerVisitor visitor{&builder};
              adapter.Accept(&visitor);
              builder.Finish();
              methods.back().Encode();
              break;
            }
            case CompilationTarget::kJavaLanguage: {
              JavaLangViewBuilder builder{package_name, layout_name, target_out};
              builder.Start();
              LayoutCompilerVisitor visitor{&builder};
              adapter.Accept(&visitor);
              builder.Finish();
              break;
            }
          }
        }
      });
    }
  });

  if (target == CompilationTarget::kDex) {
    slicer::MemView image{dex_file.CreateImage()};
    target_out.write(image.ptr<const char>(), image.size());
  }
}
}  // namespace

void CompileApkLayouts(const std::string& filename, CompilationTarget target,
                       std::ostream& target_out) {
  auto assets = android::ApkAssets::Load(filename);
  CompileApkAssetsLayouts(assets, target, target_out);
}

void CompileApkLayoutsFd(android::base::unique_fd fd, CompilationTarget target,
                         std::ostream& target_out) {
  constexpr const char* friendly_name{"viewcompiler assets"};
  auto assets = android::ApkAssets::LoadFromFd(std::move(fd), friendly_name);
  CompileApkAssetsLayouts(assets, target, target_out);
}

}  // namespace startop
