#! /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.

import random
import subprocess
import sys
import os

clang = sys.argv[1]
none_opts = 0.3

class Decl:
  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:
  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:
  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(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()
