# Copyright 2019 Google Inc. 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.

"""Generates gen_headers_<arch>.bp or generates/checks kernel headers."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import filecmp
import os
import re
import subprocess
import sys


def gen_version_h(verbose, gen_dir, version_makefile):
  """Generate linux/version.h

  Scan the version_makefile for the version info, and then generate
  linux/version.h in the gen_dir as done in kernel Makefile function
  filechk_version.h

  Args:
    verbose: Set True to print progress messages.
    gen_dir: Where to place the generated files.
    version_makefile: The makefile that contains version info.
  Return:
    If version info not found, False. Otherwise, True.
  """

  version_re = re.compile(r'VERSION\s*=\s*(\d+)')
  patchlevel_re = re.compile(r'PATCHLEVEL\s*=\s*(\d+)')
  sublevel_re = re.compile(r'SUBLEVEL\s*=\s*(\d+)')

  version_str = None
  patchlevel_str = None
  sublevel_str = None

  if verbose:
    print('gen_version_h: processing [%s]' % version_makefile)

  with open(version_makefile, 'r') as f:
    while not version_str or not patchlevel_str or not sublevel_str:
      line = f.readline()

      if not line:
        print(
            'error: gen_version_h: failed to parse kernel version from %s' %
            version_makefile)
        return False

      line = line.rstrip()

      if verbose:
        print('gen_version_h: line is %s' % line)

      if not version_str:
        match = version_re.match(line)
        if match:
          if verbose:
            print('gen_version_h: matched version [%s]' % line)
          version_str = match.group(1)
          continue

      if not patchlevel_str:
        match = patchlevel_re.match(line)
        if match:
          if verbose:
            print('gen_version_h: matched patchlevel [%s]' % line)
          patchlevel_str = match.group(1)
          continue

      if not sublevel_str:
        match = sublevel_re.match(line)
        if match:
          if verbose:
            print('gen_version_h: matched sublevel [%s]' % line)
          sublevel_str = match.group(1)
          continue

  version = int(version_str)
  patchlevel = int(patchlevel_str)
  sublevel = int(sublevel_str)

  if verbose:
    print(
        'gen_version_h: found kernel version %d.%d.%d' %
        (version, patchlevel, sublevel))

  version_h = os.path.join(gen_dir, 'linux', 'version.h')

  with open(version_h, 'w') as f:
    # This code must match the code in Makefile in the make function
    # filechk_version.h
    version_code = (version << 16) + (patchlevel << 8) + sublevel
    f.write('#define LINUX_VERSION_CODE %d\n' % version_code)
    f.write(
        '#define KERNEL_VERSION(a,b,c) ' +
        '(((a) << 16) + ((b) << 8) + (c))\n')

  return True


def scan_arch_kbuild(verbose, arch_asm_kbuild, asm_generic_kbuild, arch_include_uapi):
  """Scan arch_asm_kbuild for generated headers.

  This function processes the Kbuild file to scan for three types of files that
  need to be generated. The first type are syscall generated headers, which are
  identified by adding to the generated-y make variable. The second type are
  generic headers, which are arch-specific headers that simply wrap the
  asm-generic counterpart, and are identified by adding to the generic-y make
  variable. The third type are mandatory headers that should be present in the
  /usr/include/asm folder.

  Args:
    verbose: Set True to print progress messages.
    arch_asm_kbuild: The Kbuild file containing lists of headers to generate.
    asm_generic_kbuild: The Kbuild file containing lists of mandatory headers.
    arch_include_uapi: Headers in /arch/<arch>/include/uapi directory
  Return:
    Two lists of discovered headers, one for generated and one for generic.
  """

  generated_y_re = re.compile(r'generated-y\s*\+=\s*(\S+)')
  generic_y_re = re.compile(r'generic-y\s*\+=\s*(\S+)')
  mandatory_y_re = re.compile(r'mandatory-y\s*\+=\s*(\S+)')

  # This loop parses arch_asm_kbuild for various kinds of headers to generate.

  if verbose:
    print('scan_arch_kbuild: processing [%s]' % arch_asm_kbuild)

  generated_list = []
  generic_list = []
  arch_include_uapi_list = [os.path.basename(x) for x in arch_include_uapi]
  mandatory_pre_list = []
  mandatory_list = []


  with open(arch_asm_kbuild, 'r') as f:
    while True:
      line = f.readline()

      if not line:
        break

      line = line.rstrip()

      if verbose:
        print('scan_arch_kbuild: line is %s' % line)

      match = generated_y_re.match(line)

      if match:
        if verbose:
          print('scan_arch_kbuild: matched [%s]' % line)
        generated_list.append(match.group(1))
        continue

      match = generic_y_re.match(line)

      if match:
        if verbose:
          print('scan_arch_kbuild: matched [%s]' % line)
        generic_list.append(match.group(1))
        continue

  # This loop parses asm_generic_kbuild for various kinds of headers to generate.

  if verbose:
    print('scan_arch_kbuild: processing [%s]' % asm_generic_kbuild)

  with open(asm_generic_kbuild, 'r') as f:
    while True:
      line = f.readline()

      if not line:
        break

      line = line.rstrip()

      if verbose:
        print('scan_arch_kbuild: line is %s' % line)

      match = mandatory_y_re.match(line)

      if match:
        if verbose:
          print('scan_arch_kbuild: matched [%s]' % line)
        mandatory_pre_list.append(match.group(1))
        continue

  # Mandatory headers need to be generated if they are not already generated.
  comb_list = generic_list + generated_list + arch_include_uapi_list
  mandatory_list = [x for x in mandatory_pre_list if x not in comb_list]
  if verbose:
    print("generic")
    for x in generic_list:
      print(x)
    print("generated")
    for x in generated_list:
      print(x)
    print("mandatory")
    for x in mandatory_list:
      print(x)
    print("arch_include_uapi_list")
    for x in arch_include_uapi_list:
      print(x)

  return (generated_list, generic_list, mandatory_list)


def gen_arch_headers(
    verbose, gen_dir, arch_asm_kbuild, asm_generic_kbuild, arch_syscall_tool, arch_syscall_tbl, arch_include_uapi):
  """Process arch-specific and asm-generic uapi/asm/Kbuild to generate headers.

  The function consists of a call to scan_arch_kbuild followed by three loops.
  The first loop generates headers found and placed in the generated_list by
  scan_arch_kbuild. The second loop generates headers found and placed in the
  generic_list by the scan_arch_kbuild. The third loop generates headers found
  in mandatory_list by scan_arch_kbuild.

  The function does some parsing of file names and tool invocations. If that
  parsing fails for some reason (e.g., we don't know how to generate the
  header) or a tool invocation fails, then this function will count that as
  an error but keep processing. In the end, the function returns the number of
  errors encountered.

  Args:
    verbose: Set True to print progress messages.
    gen_dir: Where to place the generated files.
    arch_asm_kbuild: The Kbuild file containing lists of headers to generate.
    asm_generic_kbuild: The Kbuild file containing lists of mandatory headers.
    arch_syscall_tool: The arch script that generates syscall headers, or None.
    arch_syscall_tbl: The arch script that defines syscall vectors, or None.
    arch_include_uapi: Headers in arch/<arch>/include/uapi directory.
  Return:
    The number of parsing errors encountered.
  """

  error_count = 0

  # First generate the lists

  (generated_list, generic_list, mandatory_list) = scan_arch_kbuild(verbose, arch_asm_kbuild, asm_generic_kbuild ,arch_include_uapi)

  # Now we're at the first loop, which is able to generate syscall headers
  # found in the first loop, and placed in generated_list. It's okay for this
  # list to be empty. In that case, of course, the loop does nothing.

  abi_re = re.compile(r'unistd-(\S+)\.h')

  for generated in generated_list:
    gen_h = os.path.join(gen_dir, 'asm', generated)
    match = abi_re.match(generated)

    if match:
      abi = match.group(1)

      cmd = [
          '/bin/bash',
          arch_syscall_tool,
          arch_syscall_tbl,
          gen_h,
          abi,
          '',
          '__NR_SYSCALL_BASE',
      ]

      if verbose:
        print('gen_arch_headers: cmd is %s' % cmd)

      result = subprocess.call(cmd)

      if result != 0:
        print('error: gen_arch_headers: cmd %s failed %d' % (cmd, result))
        error_count += 1
    else:
      print('error: gen_arch_headers: syscall header has bad filename: %s' % generated)
      error_count += 1

  # Now we're at the second loop, which generates wrappers from arch-specific
  # headers listed in generic_list to the corresponding asm-generic header.

  for generic in generic_list:
    wrap_h = os.path.join(gen_dir, 'asm', generic)
    with open(wrap_h, 'w') as f:
      f.write('#include <asm-generic/%s>\n' % generic)

  # Now we're at the third loop, which generates wrappers from asm
  # headers listed in mandatory_list to the corresponding asm-generic header.

  for mandatory in mandatory_list:
    wrap_h = os.path.join(gen_dir, 'asm', mandatory)
    with open(wrap_h, 'w') as f:
      f.write('#include <asm-generic/%s>\n' % mandatory)
  return error_count


def run_headers_install(verbose, gen_dir, headers_install, unifdef, prefix, h):
  """Process a header through the headers_install script.

  The headers_install script does some processing of a header so that it is
  appropriate for inclusion in a userland program. This function invokes that
  script for one header file.

  The input file is a header file found in the directory named by prefix. This
  function stips the prefix from the header to generate the name of the
  processed header.

  Args:
    verbose: Set True to print progress messages.
    gen_dir: Where to place the generated files.
    headers_install: The script that munges the header.
    unifdef: The unifdef tool used by headers_install.
    prefix: The prefix to strip from h to generate the output filename.
    h: The input header to process.
  Return:
    If parsing or the tool fails, False. Otherwise, True
  """

  if not h.startswith(prefix):
    print('error: expected prefix [%s] on header [%s]' % (prefix, h))
    return False

  out_h = os.path.join(gen_dir, h[len(prefix):])
  (out_h_dirname, out_h_basename) = os.path.split(out_h)
  h_dirname = os.path.dirname(h)

  cmd = [headers_install, out_h_dirname, h_dirname, out_h_basename]

  if verbose:
    print('run_headers_install: cmd is %s' % cmd)

  env = os.environ.copy()
  env["LOC_UNIFDEF"] = unifdef
  result = subprocess.call(['sh', headers_install, out_h_dirname, h_dirname, out_h_basename], env=env)

  if result != 0:
    print('error: run_headers_install: cmd %s failed %d' % (cmd, result))
    return False

  return True


def glob_headers(prefix, rel_glob, excludes):
  """Recursively scan the a directory for headers.

  This function recursively scans the directory identified by prefix for
  headers. We don't yet have a new enough version of python3 to use the
  better glob function, so right now we assume the glob is '**/*.h'.

  The function filters out any files that match the items in excludes.

  Args:
    prefix: The directory to recursively scan for headers.
    rel_glob: The shell-style glob that identifies the header pattern.
    excludes: A list of headers to exclude from the glob.
  Return:
    A list of headers discovered with excludes excluded.
  """

  # If we had python 3.5+, we could use the fancy new glob.glob.
  # full_glob = os.path.join(prefix, rel_glob)
  # full_srcs = glob.glob(full_glob, recursive=True)

  full_dirs = [prefix]
  full_srcs = []

  while full_dirs:
    full_dir = full_dirs.pop(0)
    items = sorted(os.listdir(full_dir))

    for item in items:
      full_item = os.path.join(full_dir, item)

      if os.path.isdir(full_item):
        full_dirs.append(full_item)
        continue

      if full_item in excludes:
        continue

      if full_item.endswith('.h'):
        full_srcs.append(full_item)

  return full_srcs


def find_out(verbose, module_dir, prefix, rel_glob, excludes, outs):
  """Build a list of outputs for the genrule that creates kernel headers.

  This function scans for headers in the source tree and produces a list of
  output (generated) headers.

  Args:
    verbose: Set True to print progress messages.
    module_dir: The root directory of the kernel source.
    prefix: The prefix with in the kernel source tree to search for headers.
    rel_glob: The pattern to use when matching headers under prefix.
    excludes: A list of files to exclude from the glob.
    outs: The list to populdate with the headers that will be generated.
  Return:
    The number of errors encountered.
  """

  # Turn prefix, which is relative to the soong module, to a full prefix that
  # is relative to the Android source tree.

  full_prefix = os.path.join(module_dir, prefix)

  # Convert the list of excludes, which are relative to the soong module, to a
  # set of excludes (for easy hashing), relative to the Android source tree.

  full_excludes = set()

  if excludes:
    for exclude in excludes:
      full_exclude = os.path.join(full_prefix, exclude)
      full_excludes.add(full_exclude)

  # Glob those headers.

  full_srcs = glob_headers(full_prefix, rel_glob, full_excludes)

  # Now convert the file names, which are relative to the Android source tree,
  # to be relative to the gen dir. This means stripping off the module prefix
  # and the directory within this module.

  module_dir_sep = module_dir + os.sep
  prefix_sep = prefix + os.sep

  if verbose:
    print('find_out: module_dir_sep [%s]' % module_dir_sep)
    print('find_out: prefix_sep [%s]' % prefix_sep)

  error_count = 0

  for full_src in full_srcs:
    if verbose:
      print('find_out: full_src [%s]' % full_src)

    if not full_src.startswith(module_dir_sep):
      print('error: expected %s to start with %s' % (full_src, module_dir_sep))
      error_count += 1
      continue

    local_src = full_src[len(module_dir_sep):]

    if verbose:
      print('find_out: local_src [%s]' % local_src)

    if not local_src.startswith(prefix_sep):
      print('error: expected %s to start with %s' % (local_src, prefix_sep))
      error_count += 1
      continue

    # After stripping the module directory and the prefix, we're left with the
    # name of a header that we'll generate, relative to the base of of a the
    # the include path.

    local_out = local_src[len(prefix_sep):]

    if verbose:
      print('find_out: local_out [%s]' % local_out)

    outs.append(local_out)

  return error_count

def scan_no_export_headers(verbose, module_dir, prefix):
  """Scan include/uapi kbuild for no-export-headers

  This function processes the Kbuild file to scan for no-export files that
  should not export to usr/include/uapi which is identified by adding
  to the no-export-headers make variable.

  Args:
    verbose: Set True to print progress messages.
    module_dir: The root directory of the kernel source.
    prefix: The prefix with in the kernel source tree to search for headers.
  Return:
    lists of no-export-headers.
  """

  no_export_headers_re = re.compile(r'no-export-headers\s*\+=\s*(\S+)')
  header_re = re.compile(r'include/uapi/')
  full_dirs_ = os.path.join(module_dir, prefix)
  full_dirs = [full_dirs_]

  if verbose:
    print('scan_no_export_headers: processing [%s]' % full_dirs)

  full_srcs = []
  no_export_headers_lists = []

  while full_dirs:
    full_dir = full_dirs.pop(0)
    items = sorted(os.listdir(full_dir))

    for item in items:
      full_item = os.path.join(full_dir, item)

      if os.path.isdir(full_item):
        full_dirs.append(full_item)
        continue

      if (full_item.find('Kbuild') != -1):
        full_srcs.append(full_item)

  for full_src in full_srcs:
    with open(full_src, 'r') as f:
      while True:
        line = f.readline()

        if not line:
          break

        line = line.rstrip()

        match = no_export_headers_re.match(line)

        if match:
          if verbose:
            print('scan_no_export_headers: matched [%s]' % line)

          if (match.group(1) == "kvm.h" or
              match.group(1) == "kvm_para.h" or
              match.group(1) == "a.out.h"):
              continue

          (full_src_dir_name, full_src_base_name) = full_src.split('include/uapi/')
          no_export_header_file_name = os.path.join(os.path.dirname(full_src_base_name),match.group(1))

          if verbose:
            print('scan_no_export_headers: no_export_header_file_name = ',no_export_header_file_name)

          no_export_headers_lists.append(no_export_header_file_name)
          continue

  if verbose:
    for x in no_export_headers_lists:
      print('scan_no_export_headers: no_export_headers_lists [%s]' % x)

  return no_export_headers_lists

def gen_blueprints(
    verbose, header_arch, gen_dir, arch_asm_kbuild, asm_generic_kbuild, module_dir,
    rel_arch_asm_kbuild, rel_asm_generic_kbuild, arch_include_uapi, techpack_include_uapi):
  """Generate a blueprints file containing modules that invoke this script.

  This function generates a blueprints file that contains modules that
  invoke this script to generate kernel headers. We generate the blueprints
  file as needed, but we don't actually use the generated file. The blueprints
  file that we generate ends up in the out directory, and we can use it to
  detect if the checked-in version of the file (in the source directory) is out
  of date. This pattern occurs in the Android source tree in several places.

  Args:
    verbose: Set True to print progress messages.
    header_arch: The arch for which to generate headers.
    gen_dir: Where to place the generated files.
    arch_asm_kbuild: The Kbuild file containing lists of headers to generate.
    asm_generic_kbuild: The Kbuild file containing lists of mandatory headers.
    module_dir: The root directory of the kernel source.
    rel_arch_asm_kbuild: arch_asm_kbuild relative to module_dir.
  Return:
    The number of errors encountered.
  """
  error_count = 0

  # The old and new blueprints files. We generate the new one, but we need to
  # refer to the old one in the modules that we generate.
  old_gen_headers_bp = 'gen_headers_%s.bp' % header_arch
  new_gen_headers_bp = os.path.join(gen_dir, old_gen_headers_bp)

  # Tools and tool files.
  headers_install_sh = 'headers_install.sh'
  unifdef = 'unifdef'
  kernel_headers_py = 'kernel_headers.py'
  arm_syscall_tool = 'arch/arm/tools/syscallhdr.sh'

  # Sources
  makefile = 'Makefile'
  arm_syscall_tbl = 'arch/arm/tools/syscall.tbl'
  rel_glob = '**/*.h'
  generic_prefix = 'include/uapi'
  arch_prefix = os.path.join('arch', header_arch, generic_prefix)
  generic_src = os.path.join(generic_prefix, rel_glob)
  arch_src = os.path.join(arch_prefix, rel_glob)
  techpack_src = os.path.join('techpack/*',generic_prefix, '*',rel_glob)

  # Excluded sources, architecture specific.
  exclude_srcs = []

  if header_arch == "arm":
    exclude_srcs = ['linux/a.out.h']

  if header_arch == "arm64":
    exclude_srcs = ['linux/a.out.h', 'linux/kvm_para.h']

  no_export_headers_lists = scan_no_export_headers(verbose, module_dir, generic_prefix)

  for no_export_headers_list in no_export_headers_lists:
    exclude_srcs.append(no_export_headers_list)

  if verbose:
    for x in exclude_srcs:
      print('gen_blueprints : exclude_srcs [%s]' % x)

  # Scan the arch_asm_kbuild file for files that need to be generated and those
  # that are generic (i.e., need to be wrapped).

  (generated_list, generic_list, mandatory_list) = scan_arch_kbuild(verbose,
					arch_asm_kbuild, asm_generic_kbuild, arch_include_uapi)

  generic_out = []
  error_count += find_out(
      verbose, module_dir, generic_prefix, rel_glob, exclude_srcs, generic_out)

  arch_out = []
  error_count += find_out(
      verbose, module_dir, arch_prefix, rel_glob, None, arch_out)

  techpack_out = [x.split('include/uapi/')[1] for x in techpack_include_uapi]

  if error_count != 0:
    return error_count

  # Generate the blueprints file.

  if verbose:
    print('gen_blueprints: generating %s' % new_gen_headers_bp)

  with open(new_gen_headers_bp, 'w') as f:
    f.write('// ***** DO NOT EDIT *****\n')
    f.write('// This file is generated by %s\n' % kernel_headers_py)
    f.write('\n')
    f.write('gen_headers_srcs_%s = [\n' % header_arch)
    f.write('    "%s",\n' % rel_arch_asm_kbuild)
    f.write('    "%s",\n' % rel_asm_generic_kbuild)
    f.write('    "%s",\n' % makefile)

    if header_arch == "arm":
      f.write('    "%s",\n' % arm_syscall_tbl)

    f.write('    "%s",\n' % generic_src)
    f.write('    "%s",\n' % arch_src)
    f.write(']\n')
    f.write('\n')

    if exclude_srcs:
      f.write('gen_headers_exclude_srcs_%s = [\n' % header_arch)
      for h in exclude_srcs:
        f.write('    "%s",\n' % os.path.join(generic_prefix, h))
      f.write(']\n')
      f.write('\n')

    f.write('gen_headers_out_%s = [\n' % header_arch)

    if generated_list:
      f.write('\n')
      f.write('    // Matching generated-y:\n')
      f.write('\n')
      for h in generated_list:
        f.write('    "asm/%s",\n' % h)

    if generic_list:
      f.write('\n')
      f.write('    // Matching generic-y:\n')
      f.write('\n')
      for h in generic_list:
        f.write('    "asm/%s",\n' % h)

    if mandatory_list:
      f.write('\n')
      f.write('    // Matching mandatory-y:\n')
      f.write('\n')
      for h in mandatory_list:
        f.write('    "asm/%s",\n' % h)

    if generic_out:
      f.write('\n')
      f.write('    // From %s\n' % generic_src)
      f.write('\n')
      for h in generic_out:
        f.write('    "%s",\n' % h)

    if arch_out:
      f.write('\n')
      f.write('    // From %s\n' % arch_src)
      f.write('\n')
      for h in arch_out:
        f.write('    "%s",\n' % h)

    if techpack_out:
      f.write('\n')
      f.write('    // From %s\n' % techpack_src)
      f.write('\n')
      for h in techpack_out:
        f.write('    "%s",\n' % h)

    f.write(']\n')
    f.write('\n')

    gen_blueprints_module_name = 'qti_generate_gen_headers_%s' % header_arch

    f.write('genrule {\n')
    f.write('    // This module generates the gen_headers_<arch>.bp file\n')
    f.write('    // (i.e., a new version of this file) so that it can be\n')
    f.write('    // checked later to ensure that it matches the checked-\n')
    f.write('    // in version (this file).\n')
    f.write('    name: "%s",\n' % gen_blueprints_module_name)
    f.write('    srcs: gen_headers_srcs_%s,\n' % header_arch)
    if exclude_srcs:
      f.write('    exclude_srcs: gen_headers_exclude_srcs_%s,\n' % header_arch)

    f.write('    tool_files: ["kernel_headers.py"],\n')
    f.write('    cmd: "python3 $(location kernel_headers.py) " +\n')
    f.write('        kernel_headers_verbose +\n')
    f.write('        "--header_arch %s " +\n' % header_arch)
    f.write('        "--gen_dir $(genDir) " +\n')
    f.write('        "--arch_asm_kbuild $(location %s) " +\n' % rel_arch_asm_kbuild)
    f.write('        "--arch_include_uapi $(locations %s) " +\n' % arch_src)
    f.write('        "--asm_generic_kbuild $(location %s) " +\n' % rel_asm_generic_kbuild)
    f.write('        "blueprints " +\n')
    f.write('        "# $(in)",\n')
    f.write('    out: ["gen_headers_%s.bp"],\n' % header_arch)
    f.write('}\n')
    f.write('\n')

    f.write('genrule {\n')
    f.write('    name: "qti_generate_kernel_headers_%s",\n' % header_arch)
    f.write('    tools: [\n')
    f.write('        "%s",\n' % headers_install_sh)
    f.write('        "%s",\n' % unifdef)
    f.write('    ],\n')
    f.write('    tool_files: [\n')
    f.write('        "%s",\n' % kernel_headers_py)

    if header_arch == "arm":
      f.write('        "%s",\n' % arm_syscall_tool)

    f.write('    ],\n')
    f.write('    srcs: gen_headers_srcs_%s +[\n' % header_arch)
    f.write('        "%s",\n' % old_gen_headers_bp)
    f.write('        ":%s",\n' % gen_blueprints_module_name)
    f.write('    ],\n')

    if exclude_srcs:
      f.write('    exclude_srcs: gen_headers_exclude_srcs_%s,\n' % header_arch)

    f.write('    cmd: "python3 $(location %s) " +\n' % kernel_headers_py)
    f.write('        kernel_headers_verbose +\n')
    f.write('        "--header_arch %s " +\n' % header_arch)
    f.write('        "--gen_dir $(genDir) " +\n')
    f.write('        "--arch_asm_kbuild $(location %s) " +\n' % rel_arch_asm_kbuild)
    f.write('        "--arch_include_uapi $(locations %s) " +\n' % arch_src)
    f.write('        "--asm_generic_kbuild $(location %s) " +\n' % rel_asm_generic_kbuild)
    f.write('        "headers " +\n')
    f.write('        "--old_gen_headers_bp $(location %s) " +\n' % old_gen_headers_bp)
    f.write('        "--new_gen_headers_bp $(location :%s) " +\n' % gen_blueprints_module_name)
    f.write('        "--version_makefile $(location %s) " +\n' % makefile)

    if header_arch == "arm":
      f.write('        "--arch_syscall_tool $(location %s) " +\n' % arm_syscall_tool)
      f.write('        "--arch_syscall_tbl $(location %s) " +\n' % arm_syscall_tbl)

    f.write('        "--headers_install $(location %s) " +\n' % headers_install_sh)
    f.write('        "--unifdef $(location %s) " +\n' % unifdef)
    f.write('        "--include_uapi $(locations %s)",\n' % generic_src)
    f.write('    out: ["linux/version.h"] + gen_headers_out_%s,\n' % header_arch)
    f.write('}\n')

    return 0

def parse_bp_for_headers(file_name, headers):
  parsing_headers = False
  pattern = re.compile("gen_headers_out_[a-zA-Z0-9]+\s*=\s*\[\s*")
  with open(file_name, 'r') as f:
    for line in f:
      line = line.strip()
      if pattern.match(line):
        parsing_headers = True
        continue

      if line.find("]") != -1 and parsing_headers:
        break

      if not parsing_headers:
        continue

      if line.find("//") == 0:
        continue

      headers.add(line[1:-2])

def headers_diff(old_file, new_file):
  old_headers = set()
  new_headers = set()
  diff_detected = False

  parse_bp_for_headers(old_file, old_headers)
  parse_bp_for_headers(new_file, new_headers)

  diff = old_headers - new_headers
  if len(diff):
    diff_detected = True
    print("Headers to remove:")
    for x in diff:
      print("\t{}".format(x))

  diff = new_headers - old_headers
  if len(diff):
    diff_detected = True
    print("Headers to add:")
    for x in diff:
      print("\t{}".format(x))

  return diff_detected

def gen_headers(
    verbose, header_arch, gen_dir, arch_asm_kbuild, asm_generic_kbuild, module_dir,
    old_gen_headers_bp, new_gen_headers_bp, version_makefile,
    arch_syscall_tool, arch_syscall_tbl, headers_install, unifdef, include_uapi,
    arch_include_uapi, techpack_include_uapi):
  """Generate the kernel headers.

  This script generates the version.h file, the arch-specific headers including
  syscall-related generated files and wrappers around generic files, and uses
  the headers_install tool to process other generic uapi and arch-specific uapi
  files.

  Args:
    verbose: Set True to print progress messages.
    header_arch: The arch for which to generate headers.
    gen_dir: Where to place the generated files.
    arch_asm_kbuild: The Kbuild file containing lists of headers to generate.
    asm_generic_kbuild: The Kbuild file containing mandatory headers.
    module_dir: The root directory of the kernel source.
    old_gen_headers_bp: The old gen_headers_<arch>.bp file to check.
    new_gen_headers_bp: The new gen_headers_<arch>.bp file to check.
    version_makefile: The kernel Makefile that contains version info.
    arch_syscall_tool: The arch script that generates syscall headers.
    arch_syscall_tbl: The arch script that defines syscall vectors.
    headers_install: The headers_install tool to process input headers.
    unifdef: The unifdef tool used by headers_install.
    include_uapi: The list of include/uapi header files.
    arch_include_uapi: The list of arch/<arch>/include/uapi header files.
  Return:
    The number of errors encountered.
  """

  if headers_diff(old_gen_headers_bp, new_gen_headers_bp):
    print('error: gen_headers blueprints file is out of date, suggested fix:')
    print('#######Please add or remove the above mentioned headers from %s' % (old_gen_headers_bp))
    print('then re-run the build')
    return 1

  error_count = 0

  if not gen_version_h(verbose, gen_dir, version_makefile):
    error_count += 1

  error_count += gen_arch_headers(
      verbose, gen_dir, arch_asm_kbuild, asm_generic_kbuild, arch_syscall_tool, arch_syscall_tbl ,arch_include_uapi)

  uapi_include_prefix = os.path.join(module_dir, 'include', 'uapi') + os.sep

  arch_uapi_include_prefix = os.path.join(
      module_dir, 'arch', header_arch, 'include', 'uapi') + os.sep

  for h in include_uapi:
    if not run_headers_install(
        verbose, gen_dir, headers_install, unifdef,
        uapi_include_prefix, h):
      error_count += 1

  for h in arch_include_uapi:
    if not run_headers_install(
        verbose, gen_dir, headers_install, unifdef,
        arch_uapi_include_prefix, h):
      error_count += 1

  for h in techpack_include_uapi:
    techpack_uapi_include_prefix = os.path.join(h.split('/include/uapi')[0], 'include', 'uapi') + os.sep
    if not run_headers_install(
        verbose, gen_dir, headers_install, unifdef,
        techpack_uapi_include_prefix, h):
      error_count += 1

  return error_count

def extract_techpack_uapi_headers(verbose, module_dir):

  """EXtract list of uapi headers from techpack/* directories. We need to export
     these headers to userspace.

  Args:
      verbose: Verbose option is provided to script
      module_dir: Base directory
  Returs:
      List of uapi headers
  """

  techpack_subdir = []
  techpack_dir = os.path.join(module_dir,'techpack')
  techpack_uapi = []
  techpack_uapi_sub = []

  #get list of techpack directories under techpack/
  if os.path.isdir(techpack_dir):
    items = sorted(os.listdir(techpack_dir))
    for x in items:
      p = os.path.join(techpack_dir, x)
      if os.path.isdir(p):
        techpack_subdir.append(p)

  #Print list of subdirs obtained
  if (verbose):
    for x in techpack_subdir:
      print(x)

  #For every subdirectory get list of .h files under include/uapi and append to techpack_uapi list
  for x in techpack_subdir:
    techpack_uapi_path = os.path.join(x, 'include/uapi')
    if (os.path.isdir(techpack_uapi_path)):
      techpack_uapi_sub = []
      find_out(verbose, x, 'include/uapi', '**/*.h', None, techpack_uapi_sub)
      tmp = [os.path.join(techpack_uapi_path, y) for y in techpack_uapi_sub]
      techpack_uapi = techpack_uapi + tmp

  if (verbose):
    for x in techpack_uapi:
      print(x)

  return techpack_uapi

def main():
  """Parse command line arguments and perform top level control."""

  parser = argparse.ArgumentParser(
      description=__doc__,
      formatter_class=argparse.RawDescriptionHelpFormatter)

  # Arguments that apply to every invocation of this script.

  parser.add_argument(
      '--verbose',
      action='store_true',
      help='Print output that describes the workings of this script.')
  parser.add_argument(
      '--header_arch',
      required=True,
      help='The arch for which to generate headers.')
  parser.add_argument(
      '--gen_dir',
      required=True,
      help='Where to place the generated files.')
  parser.add_argument(
      '--arch_asm_kbuild',
      required=True,
      help='The Kbuild file containing lists of headers to generate.')
  parser.add_argument(
      '--asm_generic_kbuild',
      required=True,
      help='The Kbuild file containing lists of mandatory headers.')
  parser.add_argument(
      '--arch_include_uapi',
      required=True,
      nargs='*',
      help='The list of arch/<arch>/include/uapi header files.')

  # The modes.

  subparsers = parser.add_subparsers(
      dest='mode',
      help='Select mode')
  parser_blueprints = subparsers.add_parser(
      'blueprints',
      help='Generate the gen_headers_<arch>.bp file.')
  parser_headers = subparsers.add_parser(
      'headers',
      help='Check blueprints, then generate kernel headers.')

  # Arguments that apply to headers mode.

  parser_headers.add_argument(
      '--old_gen_headers_bp',
      required=True,
      help='The old gen_headers_<arch>.bp file to check.')
  parser_headers.add_argument(
      '--new_gen_headers_bp',
      required=True,
      help='The new gen_headers_<arch>.bp file to check.')
  parser_headers.add_argument(
      '--version_makefile',
      required=True,
      help='The kernel Makefile that contains version info.')
  parser_headers.add_argument(
      '--arch_syscall_tool',
      help='The arch script that generates syscall headers, if applicable.')
  parser_headers.add_argument(
      '--arch_syscall_tbl',
      help='The arch script that defines syscall vectors, if applicable.')
  parser_headers.add_argument(
      '--headers_install',
      required=True,
      help='The headers_install tool to process input headers.')
  parser_headers.add_argument(
      '--unifdef',
      required=True,
      help='The unifdef tool used by headers_install.')
  parser_headers.add_argument(
      '--include_uapi',
      required=True,
      nargs='*',
      help='The list of include/uapi header files.')

  args = parser.parse_args()

  if args.verbose:
    print('mode [%s]' % args.mode)
    print('header_arch [%s]' % args.header_arch)
    print('gen_dir [%s]' % args.gen_dir)
    print('arch_asm_kbuild [%s]' % args.arch_asm_kbuild)
    print('asm_generic_kbuild [%s]' % args.asm_generic_kbuild)

  # Extract the module_dir from args.arch_asm_kbuild and rel_arch_asm_kbuild.

  rel_arch_asm_kbuild = os.path.join(
      'arch', args.header_arch, 'include/uapi/asm/Kbuild')

  suffix = os.sep + rel_arch_asm_kbuild

  if not args.arch_asm_kbuild.endswith(suffix):
    print('error: expected %s to end with %s' % (args.arch_asm_kbuild, suffix))
    return 1

  module_dir = args.arch_asm_kbuild[:-len(suffix)]

  rel_asm_generic_kbuild = os.path.join('include/uapi/asm-generic', os.path.basename(args.asm_generic_kbuild))


  if args.verbose:
    print('module_dir [%s]' % module_dir)

  techpack_include_uapi = []


  if args.mode == 'blueprints':
    return gen_blueprints(
        args.verbose, args.header_arch, args.gen_dir, args.arch_asm_kbuild,
        args.asm_generic_kbuild, module_dir, rel_arch_asm_kbuild, rel_asm_generic_kbuild, args.arch_include_uapi, techpack_include_uapi)

  if args.mode == 'headers':
    if args.verbose:
      print('old_gen_headers_bp [%s]' % args.old_gen_headers_bp)
      print('new_gen_headers_bp [%s]' % args.new_gen_headers_bp)
      print('version_makefile [%s]' % args.version_makefile)
      print('arch_syscall_tool [%s]' % args.arch_syscall_tool)
      print('arch_syscall_tbl [%s]' % args.arch_syscall_tbl)
      print('headers_install [%s]' % args.headers_install)
      print('unifdef [%s]' % args.unifdef)

    return gen_headers(
        args.verbose, args.header_arch, args.gen_dir, args.arch_asm_kbuild,
        args.asm_generic_kbuild, module_dir, args.old_gen_headers_bp, args.new_gen_headers_bp,
        args.version_makefile, args.arch_syscall_tool, args.arch_syscall_tbl,
        args.headers_install, args.unifdef, args.include_uapi, args.arch_include_uapi,
        techpack_include_uapi)

  print('error: unknown mode: %s' % args.mode)
  return 1


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