#!/usr/bin/env python
#
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
#
#
#
# scramble-tree.py:  (See scramble-tree.py --help.)
#
# Makes multiple random file changes to a directory tree, for testing.
#
# This script will add some new files, remove some existing files, add
# text to some existing files, and delete text from some existing
# files.  It will also leave some files completely untouched.
#
# The exact set of changes made is always the same for identical trees,
# where "identical" means the names of files and directories are the
# same, and they are arranged in the same tree structure (the actual
# contents of files may differ).  If two are not identical, the sets of
# changes scramble-tree.py will make may differ arbitrarily.
#
# Directories named .svn/ and CVS/ are ignored.
#
# Example scenario, starting with a pristine Subversion working copy:
#
#   $ ls
#   foo/
#   $ svn st foo
#   $ cp -r foo bar
#   $ svn st bar
#   $ scramble-tree.py foo
#   $ svn st foo
#   [... see lots of scary status output ...]
#   $ scramble-tree.py bar
#   [... see the exact same scary status output ...]
#   $ scramble-tree.py foo
#   [... see a new bunch of scary status output ...]
#   $

import os
import sys
import getopt
try:
  my_getopt = getopt.gnu_getopt
except AttributeError:
  my_getopt = getopt.getopt
import random
from hashlib import md5 as hashlib_md5
import base64


class VCActions:
  def __init__(self):
    pass
  def add_file(self, path):
    """Add an existing file to version control."""
    pass
  def remove_file(self, path):
    """Remove an existing file from version control, and delete it."""
    pass


class NoVCActions(VCActions):
  def remove_file(self, path):
    os.unlink(path)


class CVSActions(VCActions):
  def add_file(self, path):
    cwd = os.getcwd()
    try:
      dirname, basename = os.path.split(path)
      os.chdir(os.path.join(cwd, dirname))
      os.system('cvs -Q add -m "Adding file to repository" "%s"' % (basename))
    finally:
      os.chdir(cwd)
  def remove_file(self, path):
    cwd = os.getcwd()
    try:
      dirname, basename = os.path.split(path)
      os.chdir(os.path.join(cwd, dirname))
      os.system('cvs -Q rm -f "%s"' % (basename))
    finally:
      os.chdir(cwd)


class SVNActions(VCActions):
  def add_file(self, path):
    os.system('svn add --quiet "%s"' % (path))
  def remove_file(self, path):
    os.remove(path)
    os.system('svn rm --quiet --force "%s"' % (path))


class hashDir:
  """Given a directory, creates a string containing all directories
  and files under that directory (sorted alphanumerically) and makes a
  base64-encoded md5 hash of the resulting string.  Call
  hashDir.gen_seed() to generate a seed value for this tree."""

  def __init__(self, rootdir):
    self.allfiles = []
    for dirpath, dirs, files in os.walk(rootdir):
      self.walker_callback(len(rootdir), dirpath, dirs + files)

  def gen_seed(self):
    # Return a base64-encoded (kinda ... strip the '==\n' from the
    # end) MD5 hash of sorted tree listing.
    self.allfiles.sort()
    return base64.encodestring(hashlib_md5(''.join(self.allfiles)).digest())[:-3]

  def walker_callback(self, baselen, dirname, fnames):
    if ((dirname == '.svn') or (dirname == 'CVS')):
      return
    self.allfiles.append(dirname[baselen:])
    for filename in fnames:
      path = os.path.join(dirname, filename)
      if not os.path.isdir(path):
        self.allfiles.append(path[baselen:])


class Scrambler:
  def __init__(self, seed, vc_actions, dry_run, quiet):
    if not quiet:
      print('SEED: ' + seed)

    self.rand = random.Random(seed)
    self.vc_actions = vc_actions
    self.dry_run = dry_run
    self.quiet = quiet
    self.ops = []  ### ["add" | "munge", path]
    self.greeking = """
======================================================================
This is some text that was inserted into this file by the lovely and
talented scramble-tree.py script.
======================================================================
"""

  ### Helpers
  def shrink_list(self, list, remove_count):
    if len(list) <= remove_count:
      return []
    for i in range(remove_count):
      j = self.rand.randrange(len(list) - 1)
      del list[j]
    return list

  def _make_new_file(self, dir):
    i = 0
    path = None
    for i in range(99999):
      path = os.path.join(dir, "newfile.%05d.txt" % i)
      if not os.path.exists(path):
        open(path, 'w').write(self.greeking)
        return path
    raise Exception("Ran out of unique new filenames in directory '%s'" % dir)

  ### File Mungers
  def _mod_append_to_file(self, path):
    if not self.quiet:
      print('append_to_file: %s' % path)
    if self.dry_run:
      return
    fh = open(path, "a")
    fh.write(self.greeking)
    fh.close()

  def _mod_remove_from_file(self, path):
    if not self.quiet:
      print('remove_from_file: %s' % path)
    if self.dry_run:
      return
    lines = self.shrink_list(open(path, "r").readlines(), 5)
    open(path, "w").writelines(lines)

  def _mod_delete_file(self, path):
    if not self.quiet:
      print('delete_file: %s' % path)
    if self.dry_run:
      return
    self.vc_actions.remove_file(path)

  ### Public Interfaces
  def get_randomizer(self):
    return self.rand

  def schedule_munge(self, path):
    self.ops.append(tuple(["munge", path]))

  def schedule_addition(self, dir):
    self.ops.append(tuple(["add", dir]))

  def enact(self, limit):
    num_ops = len(self.ops)
    if limit == 0:
      return
    elif limit > 0 and limit <= num_ops:
      self.ops = self.shrink_list(self.ops, num_ops - limit)
    for op, path in self.ops:
      if op == "add":
        path = self._make_new_file(path)
        if not self.quiet:
          print("add_file: %s" % path)
        if self.dry_run:
          return
        self.vc_actions.add_file(path)
      elif op == "munge":
        file_mungers = [self._mod_append_to_file,
                        self._mod_append_to_file,
                        self._mod_append_to_file,
                        self._mod_remove_from_file,
                        self._mod_remove_from_file,
                        self._mod_remove_from_file,
                        self._mod_delete_file,
                        ]
        self.rand.choice(file_mungers)(path)


def usage(retcode=255):
  print('Usage: %s [OPTIONS] DIRECTORY' % (sys.argv[0]))
  print('')
  print('Options:')
  print('    --help, -h  : Show this usage message.')
  print('    --seed ARG  : Use seed ARG to scramble the tree.')
  print('    --use-svn   : Use Subversion (as "svn") to perform file additions')
  print('                  and removals.')
  print('    --use-cvs   : Use CVS (as "cvs") to perform file additions')
  print('                  and removals.')
  print('    --dry-run   : Don\'t actually change the disk.')
  print('    --limit N   : Limit the scrambling to a maximum of N operations.')
  print('    --quiet, -q : Run in stealth mode!')
  sys.exit(retcode)


def walker_callback(scrambler, dirname, fnames):
  if ((dirname.find('.svn') != -1) or dirname.find('CVS') != -1):
    return
  rand = scrambler.get_randomizer()
  if rand.randrange(5) == 1:
    scrambler.schedule_addition(dirname)
  for filename in fnames:
    path = os.path.join(dirname, filename)
    if not os.path.isdir(path) and rand.randrange(3) == 1:
      scrambler.schedule_munge(path)


def main():
  seed = None
  vc_actions = NoVCActions()
  dry_run = 0
  quiet = 0
  limit = None

  # Mm... option parsing.
  optlist, args = my_getopt(sys.argv[1:], "hq",
                            ['seed=', 'use-svn', 'use-cvs',
                             'help', 'quiet', 'dry-run', 'limit='])
  for opt, arg in optlist:
    if opt == '--help' or opt == '-h':
      usage(0)
    if opt == '--seed':
      seed = arg
    if opt == '--use-svn':
      vc_actions = SVNActions()
    if opt == '--use-cvs':
      vc_actions = CVSActions()
    if opt == '--dry-run':
      dry_run = 1
    if opt == '--limit':
      limit = int(arg)
    if opt == '--quiet' or opt == '-q':
      quiet = 1

  # We need at least a path to work with, here.
  argc = len(args)
  if argc < 1 or argc > 1:
    usage()
  rootdir = args[0]

  # If a seed wasn't provide, calculate one.
  if seed is None:
    seed = hashDir(rootdir).gen_seed()
  scrambler = Scrambler(seed, vc_actions, dry_run, quiet)
  for dirpath, dirs, files in os.walk(rootdir):
    walker_callback(scrambler, dirpath, dirs + files)
  scrambler.enact(limit)

if __name__ == '__main__':
  main()
