# pylint: disable=g-direct-third-party-import
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# 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.

"""A tool for extracting resource files from an AAR.

An AAR may contain resources under the /res directory. This tool extracts all
of the resources into a directory. If no resources exist, it creates an
empty.xml file that defines no resources.

In the future, this script may be extended to also extract assets.
"""

import os
import sys
import zipfile

from tools.android import junction
from third_party.py import gflags

FLAGS = gflags.FLAGS

gflags.DEFINE_string("input_aar", None, "Input AAR")
gflags.MarkFlagAsRequired("input_aar")
gflags.DEFINE_string("output_res_dir", None, "Output resources directory")
gflags.MarkFlagAsRequired("output_res_dir")
gflags.DEFINE_string("output_assets_dir", None, "Output assets directory")


def ExtractResources(aar, output_res_dir):
  """Extract resource from an `aar` file to the `output_res_dir` directory."""
  aar_contains_no_resources = True
  output_res_dir_abs = os.path.abspath(output_res_dir)
  for name in aar.namelist():
    if name.startswith("res/") and not name.endswith("/"):
      ExtractOneFile(aar, name, output_res_dir_abs)
      aar_contains_no_resources = False
  if aar_contains_no_resources:
    empty_xml_filename = output_res_dir + "/res/values/empty.xml"
    WriteFileWithJunctions(empty_xml_filename, b"<resources/>")


def ExtractAssets(aar, output_assets_dir):
  """Extracts assets from an `aar` file to the `output_assets_dir` directory."""
  aar_contains_no_assets = True
  output_assets_dir_abs = os.path.abspath(output_assets_dir)
  for name in aar.namelist():
    if name.startswith("assets/") and not name.endswith("/"):
      ExtractOneFile(aar, name, output_assets_dir_abs)
      aar_contains_no_assets = False
  if aar_contains_no_assets:
    # aapt will ignore this file and not print an error message, because it
    # thinks that it is a swap file. We need to create at least one file so that
    # Bazel does not complain that the output tree artifact was not created.
    empty_asset_filename = (output_assets_dir +
                            "/assets/empty_asset_generated_by_bazel~")
    WriteFileWithJunctions(empty_asset_filename, b"")


def WriteFileWithJunctions(filename, content):
  """Writes file including creating any junctions or directories necessary."""
  def _WriteFile(filename):
    with open(filename, "wb") as openfile:
      openfile.write(content)

  if os.name == "nt":
    # Create a junction to the parent directory, because its path might be too
    # long. Creating the junction also creates all parent directories.
    with junction.TempJunction(os.path.dirname(filename)) as junc:
      filename = os.path.join(junc, os.path.basename(filename))
      # Write the file within scope of the TempJunction, otherwise the path in
      # `filename` would no longer be valid.
      _WriteFile(filename)
  else:
    os.makedirs(os.path.dirname(filename))
    _WriteFile(filename)


def ExtractOneFile(aar, name, abs_output_dir):
  """Extract one file from the aar to the output directory."""
  if os.name == "nt":
    fullpath = os.path.normpath(os.path.join(abs_output_dir, name))
    if name[-1] == "/":
      # The zip entry is a directory. Create a junction to it, which also
      # takes care of creating the directory and all of its parents in a
      # longpath-safe manner.
      # We must pretend to have extracted this directory, even if it's
      # empty, therefore we mustn't rely on creating it as a parent
      # directory of a subsequently extracted zip entry (because there may
      # be no such subsequent entry).
      with junction.TempJunction(fullpath.rstrip("/")) as juncpath:
        pass
    else:
      # The zip entry is a file. Create a junction to its parent directory,
      # then open the compressed entry as a file object, so we can extract
      # the data even if the extracted file's path would be too long.
      # The tradeoff is that we lose the permission bits of the compressed
      # file, but Unix permissions don't mean much on Windows anyway.
      with junction.TempJunction(os.path.dirname(fullpath)) as juncpath:
        extracted_path = os.path.join(juncpath, os.path.basename(fullpath))
        with aar.open(name) as src_fd:
          with open(extracted_path, "wb") as dest_fd:
            dest_fd.write(src_fd.read())
  else:
    aar.extract(name, abs_output_dir)


def main():
  with zipfile.ZipFile(FLAGS.input_aar, "r") as aar:
    ExtractResources(aar, FLAGS.output_res_dir)
    if FLAGS.output_assets_dir is not None:
      ExtractAssets(aar, FLAGS.output_assets_dir)

if __name__ == "__main__":
  FLAGS(sys.argv)
  main()
