#! /usr/bin/env python

# To use:
#  1) Update the 'decls' list below with your fuzzing configuration.
#  2) Run with the clang binary as the command-line argument.

from __future__ import absolute_import, division, print_function
import random
import subprocess
import sys
import os

clang = sys.argv[1]
none_opts = 0.3

class Decl(object):
  def __init__(self, text, depends=[], provides=[], conflicts=[]):
    self.text = text
    self.depends = depends
    self.provides = provides
    self.conflicts = conflicts

  def valid(self, model):
    for i in self.depends:
      if i not in model.decls:
        return False
    for i in self.conflicts:
      if i in model.decls:
        return False
    return True

  def apply(self, model, name):
    for i in self.provides:
      model.decls[i] = True
    model.source += self.text % {'name': name}

decls = [
  Decl('struct X { int n; };\n', provides=['X'], conflicts=['X']),
  Decl('static_assert(X{.n=1}.n == 1, "");\n', depends=['X']),
  Decl('X %(name)s;\n', depends=['X']),
]

class FS(object):
  def __init__(self):
    self.fs = {}
    self.prevfs = {}

  def write(self, path, contents):
    self.fs[path] = contents

  def done(self):
    for f, s in self.fs.items():
      if self.prevfs.get(f) != s:
        f = file(f, 'w')
        f.write(s)
        f.close()

    for f in self.prevfs:
      if f not in self.fs:
        os.remove(f)

    self.prevfs, self.fs = self.fs, {}

fs = FS()

class CodeModel(object):
  def __init__(self):
    self.source = ''
    self.modules = {}
    self.decls = {}
    self.i = 0

  def make_name(self):
    self.i += 1
    return 'n' + str(self.i)

  def fails(self):
    fs.write('module.modulemap',
          ''.join('module %s { header "%s.h" export * }\n' % (m, m)
                  for m in self.modules.keys()))

    for m, (s, _) in self.modules.items():
      fs.write('%s.h' % m, s)

    fs.write('main.cc', self.source)
    fs.done()

    return subprocess.call([clang, '-std=c++11', '-c', '-fmodules', 'main.cc', '-o', '/dev/null']) != 0

def generate():
  model = CodeModel()
  m = []

  try:
    for d in mutations(model):
      d(model)
      m.append(d)
    if not model.fails():
      return
  except KeyboardInterrupt:
    print()
    return True

  sys.stdout.write('\nReducing:\n')
  sys.stdout.flush()

  try:
    while True:
      assert m, 'got a failure with no steps; broken clang binary?'
      i = random.choice(list(range(len(m))))
      x = m[0:i] + m[i+1:]
      m2 = CodeModel()
      for d in x:
        d(m2)
      if m2.fails():
        m = x
        model = m2
      else:
        sys.stdout.write('.')
        sys.stdout.flush()
  except KeyboardInterrupt:
    # FIXME: Clean out output directory first.
    model.fails()
    return model

def choose(options):
  while True:
    i = int(random.uniform(0, len(options) + none_opts))
    if i >= len(options):
      break
    yield options[i]

def mutations(model):
  options = [create_module, add_top_level_decl]
  for opt in choose(options):
    yield opt(model, options)

def create_module(model, options):
  n = model.make_name()
  def go(model):
    model.modules[n] = (model.source, model.decls)
    (model.source, model.decls) = ('', {})
  options += [lambda model, options: add_import(model, options, n)]
  return go

def add_top_level_decl(model, options):
  n = model.make_name()
  d = random.choice([decl for decl in decls if decl.valid(model)])
  def go(model):
    if not d.valid(model):
      return
    d.apply(model, n)
  return go

def add_import(model, options, module_name):
  def go(model):
    if module_name in model.modules:
      model.source += '#include "%s.h"\n' % module_name
      model.decls.update(model.modules[module_name][1])
  return go

sys.stdout.write('Finding bug: ')
while True:
  if generate():
    break
  sys.stdout.write('.')
  sys.stdout.flush()
