# Copyright (c) 2021, Alliance for Open Media. All rights reserved.
#
# This source code is subject to the terms of the BSD 2 Clause License and
# the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
# was not distributed with this source code in the LICENSE file, you can
# obtain it at www.aomedia.org/license/software. If the Alliance for Open
# Media Patent License 1.0 was not distributed with this source code in the
# PATENTS file, you can obtain it at www.aomedia.org/license/patent.
#

import os
import sys


def is_code_file(filename):
  return filename.endswith(".c") or filename.endswith(".h")


def is_simd_file(filename):
  simd_keywords = [
      "avx2", "sse2", "sse3", "ssse3", "sse4", "dspr2", "neon", "msa", "simd",
      "x86"
  ]
  for keyword in simd_keywords:
    if filename.find(keyword) >= 0:
      return True
  return False


def get_code_file_list(path, exclude_file_set):
  code_file_list = []
  for cur_dir, sub_dir, file_list in os.walk(path):
    for filename in file_list:
      if is_code_file(filename) and not is_simd_file(
          filename) and filename not in exclude_file_set:
        file_path = os.path.join(cur_dir, filename)
        code_file_list.append(file_path)
  return code_file_list


def av1_exclude_file_set():
  exclude_file_set = {
      "cfl_ppc.c",
      "ppc_cpudetect.c",
  }
  return exclude_file_set


def get_av1_pp_command(fake_header_dir, code_file_list):
  pre_command = "gcc -w -nostdinc -E -I./ -I../ -I" + fake_header_dir + (" "
                                                                         "-D'ATTRIBUTE_PACKED='"
                                                                         " "
                                                                         "-D'__attribute__(x)='"
                                                                         " "
                                                                         "-D'__inline__='"
                                                                         " "
                                                                         "-D'float_t=float'"
                                                                         " "
                                                                         "-D'DECLARE_ALIGNED(n,"
                                                                         " typ,"
                                                                         " "
                                                                         "val)=typ"
                                                                         " val'"
                                                                         " "
                                                                         "-D'volatile='"
                                                                         " "
                                                                         "-D'AV1_K_MEANS_DIM=2'"
                                                                         " "
                                                                         "-D'INLINE='"
                                                                         " "
                                                                         "-D'AOM_INLINE='"
                                                                         " "
                                                                         "-D'AOM_FORCE_INLINE='"
                                                                         " "
                                                                         "-D'inline='"
                                                                         )
  return pre_command + " " + " ".join(code_file_list)


def modify_av1_rtcd(build_dir):
  av1_rtcd = os.path.join(build_dir, "config/av1_rtcd.h")
  fp = open(av1_rtcd)
  string = fp.read()
  fp.close()
  new_string = string.replace("#ifdef RTCD_C", "#if 0")
  fp = open(av1_rtcd, "w")
  fp.write(new_string)
  fp.close()


def preprocess_av1(aom_dir, build_dir, fake_header_dir):
  cur_dir = os.getcwd()
  output = os.path.join(cur_dir, "av1_pp.c")
  path_list = [
      os.path.join(aom_dir, "av1/encoder"),
      os.path.join(aom_dir, "av1/common")
  ]
  code_file_list = []
  for path in path_list:
    path = os.path.realpath(path)
    code_file_list.extend(get_code_file_list(path, av1_exclude_file_set()))
  modify_av1_rtcd(build_dir)
  cmd = get_av1_pp_command(fake_header_dir, code_file_list) + " >" + output
  os.chdir(build_dir)
  os.system(cmd)
  os.chdir(cur_dir)


if __name__ == "__main__":
  aom_dir = sys.argv[1]
  build_dir = sys.argv[2]
  fake_header_dir = sys.argv[3]
  preprocess_av1(aom_dir, build_dir, fake_header_dir)
