#! /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(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(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()
