#!/usr/bin/python
# Copyright 2022 The Cobalt 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.
"""Copy the out directory and filter out files and folders we don't need.

This script filters out large files, e.g. ".mp4" and ".deb" files, and
intermediate build files, that are not critical to the ability to launch Cobalt.
The purpose of applying this filter is to reduce the size of the destination out
folder.

Usage:
  copy_and_filter_out_dir.py -s <source_out_dir> -d <dest_out_dir>

source_out_dir is the absolute path to the source folder from which the out
directory is copied.
e.g. '/usr/local/google/home/{username}/cobalt/src/out/linux-x64x11_qa
dest_out_dir the absolute path to the destination folder into which the out
directory is copied.
e.g. '/tmp/out/linux-x64x11_qa'

"""

import argparse
import logging
import os
import shutil
import sys


def _FilterFile(file_name):
  name, extension = os.path.splitext(file_name)
  return 'ninja' in file_name or name in [
      'bytecode_builtins_list_generator', 'gyp-win-tool', 'mksnapshot',
      'protoc', 'torque', 'v8_build_config'
  ] or extension in ['.mp4', '.deb', '.d', '.o', '.stamp', '.tmp', '.rsp']


def _FilterDir(dir_name):
  filter_dir = ['gen', 'gypfiles', 'obj', 'obj.host', 'gradle', 'pyproto']
  return dir_name in filter_dir


def _IterateAndFilter(source_path, dest_path, copymap):
  """Iterate the source_path and filter out files and folders we don't need.

  Add the source to destination file pairs to the copy map.

  Args:
    source_path: the absolute path to the source folder to be copied from.
    dest_path: the absolute path to the destination folder to be copied to.
    copymap: the map of file pairs from source to destination.
  """

  # Iterate and filter files
  files = next(os.walk(source_path))[2]
  for f in files:
    if not _FilterFile(f):
      source_file_path = os.path.join(source_path, f)
      dest_file_path = os.path.join(dest_path, f)
      copymap[source_file_path] = dest_file_path

  # Iterate and filter directories
  dirs = next(os.walk(source_path))[1]
  for d in dirs:
    if not _FilterDir(d):
      source_dir_path = os.path.join(source_path, d)
      dest_dir_path = os.path.join(dest_path, d)
      _IterateAndFilter(source_dir_path, dest_dir_path, copymap)


def CopyAndFilterOutDir(source_out_dir, dest_out_dir):
  """Copy the out directory and filter out files and folders.

  Args:
    source_out_dir: the absolute path to the source folder from which the out
      directory is copied.
    dest_out_dir: the absolute path to the destination folder into which the out
      directory is copied.
  Returns:
    0 on success.
  """
  source_out_dir = os.path.abspath(source_out_dir)
  dest_out_dir = os.path.abspath(dest_out_dir)
  logging.info('Copying and filtering %s to %s', source_out_dir, dest_out_dir)

  copies = {}

  if not os.path.exists(source_out_dir):
    logging.error('Skipping CopyAndFilterOutDir, %s does not exist',
                  source_out_dir)
    return 0

  _IterateAndFilter(source_out_dir, dest_out_dir, copies)

  # Add build_info json to the out directory root.
  source_build_info = os.path.join(source_out_dir, 'gen', 'build_info.json')
  dest_build_info = os.path.join(dest_out_dir, 'build_info.json')
  copies[source_build_info] = dest_build_info

  for source, dest in copies.items():
    dirname = os.path.dirname(dest)
    if not os.path.exists(dirname):
      os.makedirs(dirname)
    shutil.copy(source, dest)
    logging.info('%s -> %s', source, dest)

  logging.info('Done.')
  return 0


def main():
  logging_format = '%(asctime)s %(levelname)-8s %(message)s'
  logging_level = logging.INFO
  logging.basicConfig(
      level=logging_level, format=logging_format, datefmt='%m-%d %H:%M')

  parser = argparse.ArgumentParser()
  parser.add_argument(
      '-s',
      '--source_out_dir',
      required=True,
      help='The absolute path to the source folder from which'
      'the out directory is copied.')
  parser.add_argument(
      '-d',
      '--dest_out_dir',
      required=True,
      help='The absolute path to the destination folder into which'
      'the out directory is copied.')
  args = parser.parse_args()

  return CopyAndFilterOutDir(args.source_out_dir, args.dest_out_dir)


if __name__ == '__main__':
  sys.exit(main())
