#!/usr/bin/env python3
#
# Copyright 2015 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generate or update an existing config (.options file) for libfuzzer test.

Invoked by GN from fuzzer_test.gni.
"""

import argparse
import os

from configparser import ConfigParser


def AddSectionOptions(config, section_name, options):
  """Add |options| to the |section_name| section of |config|.

  Throws an
  assertion error if any option in |options| does not have exactly two
  elements.
  """
  if not options:
    return

  config.add_section(section_name)
  for option_and_value in options:
    assert len(option_and_value) == 2, ('%s is not an option, value pair' %
                                        option_and_value)

    config.set(section_name, *option_and_value)


def main():
  parser = argparse.ArgumentParser(description='Generate fuzzer config.')
  parser.add_argument('--config', required=True)
  parser.add_argument('--dict')
  parser.add_argument('--libfuzzer_options', nargs='+', default=[])
  parser.add_argument('--centipede_options', nargs='+', default=[])
  parser.add_argument('--asan_options', nargs='+', default=[])
  parser.add_argument('--msan_options', nargs='+', default=[])
  parser.add_argument('--ubsan_options', nargs='+', default=[])
  parser.add_argument('--grammar_options', nargs='+', default=[])
  parser.add_argument('--environment_variables',
                      nargs='+',
                      default=[],
                      choices=['AFL_DRIVER_DONT_DEFER=1'])
  args = parser.parse_args()

  # Script shouldn't be invoked without any arguments, but just in case.
  if not (args.dict or args.libfuzzer_options or args.environment_variables
          or args.asan_options or args.msan_options or args.ubsan_options
          or args.grammar_options):
    return

  config = ConfigParser()
  libfuzzer_options = []
  if args.dict:
    libfuzzer_options.append(('dict', os.path.basename(args.dict)))
  libfuzzer_options.extend(
      option.split('=') for option in args.libfuzzer_options)

  AddSectionOptions(config, 'libfuzzer', libfuzzer_options)

  centipede_options = []
  if args.dict:
    centipede_options.append(('dictionary', os.path.basename(args.dict)))
  centipede_options.extend(
      option.split('=') for option in args.centipede_options)
  AddSectionOptions(config, 'centipede', centipede_options)

  AddSectionOptions(config, 'asan',
                    [option.split('=') for option in args.asan_options])

  AddSectionOptions(config, 'msan',
                    [option.split('=') for option in args.msan_options])

  AddSectionOptions(config, 'ubsan',
                    [option.split('=') for option in args.ubsan_options])

  AddSectionOptions(config, 'grammar',
                    [option.split('=') for option in args.grammar_options])

  AddSectionOptions(
      config, 'env',
      [option.split('=') for option in args.environment_variables])

  # Generate .options file.
  config_path = args.config
  with open(config_path, 'w') as options_file:
    options_file.write(
        '# This is an automatically generated config for ClusterFuzz.\n')
    config.write(options_file)


if __name__ == '__main__':
  main()
