#!/usr/bin/env python3.5

import sys

sys.path.insert(0, './pyyaml/lib3/')

import yaml, glob, collections

config_paths = glob.glob('./configs/*')


def p(s):
  print(s, end="", file=sys.stderr, flush=True)

def print_collection(l):
  c = collections.Counter(l)
  for name, count in c.most_common():
    print('{0: <5} {1}'.format(count, name))


filenames = []

for path in config_paths:
  filenames.append(path.split("_")[-1])

p('parsing {} configs'.format(len(config_paths)))

objects = {}
bad = []

for path in config_paths:
  with open(path, 'r') as f:
    try:
      o = yaml.safe_load(f.read())
    except (yaml.scanner.ScannerError, yaml.parser.ParserError):
      bad.append(path)
      p('x')
      continue
    p('.')
    objects[path] = o
p('\n')
p('\n')

bad = []
p('checking for lists')
for path in objects:
  o = objects[path]
  if not isinstance(o, list):
    bad.append(path)
    p('x')
    continue
  p('.')
p('\n')
p('\n')

for path in bad:
  del objects[path]

p('checking for dicts')
for path in objects:
  o = objects[path]
  for task in o:
    if not isinstance(task, dict):
      p('x')
      continue
    p('.')
p('\n')
p('\n')

print('dotbot user study')
print('=================')

print()
print('```')
print('config filenames:')
print_collection(filenames)

print()
print('({} failed to parse or were invalid)'.format(len(bad)))

names = []
expected = 'link clean shell aliases meta'.split()
unexpected = []
for path in objects:
  o = objects[path]
  for task in o:
    for key in task:
      if key not in expected and not key.startswith('~'):
        unexpected.append(key)
        p('unexpected key: {} in {}\n'.format(key, path))
      names.append(key)

print()
print('tasks:')
print_collection(names)

categories = {
    'chmod': ['chmod '],
    'cp': ['cp '],
    'mkdir': ['mkdir '],
    'make': ['make '],
    'git submodule update': [
      'git submodule update',
      'git submodule foreach pull',
      'git update-submodules',
      'git submodule init',
      'git pull && git submodule update',
      'git submodule sync',
    ],
    'curl/wget': ['curl', 'wget'],
    'touch': ['touch'],
    'git clone': ['git clone'],
    'git config': ['git config'],
    'git pull': ['git pull'],
    'vim plugin/bundle': [
      'vim +Plugin',
      'vim -f +Plugin',
      'vim +Bundle',
      'vim +NeoBundle',
      'vim -c Plugin',
      'vim -c "Plugin',
      'vim -c "Bundle',
    ],
    'rm': ['rm '],
    'source': ['source '],
    'pip install': ['pip install'],
    'gem install': ['gem install'],
    'npm install': ['npm install'],
    'brew install': ['brew install', 'brew cask install'],
    'ln -s': ['ln -s'],
    'sudo': ['sudo'],
    'uncategorized': []
}

separated = {}
for category in categories:
  separated[category] = []

uncategorized = []

shell_commands = []
for path in objects:
  o = objects[path]
  for task in o:
    for key in task:
      if key == 'shell':
        cmds = task[key]
        for cmd in cmds:
          if isinstance(cmd, str):
            shell_commands.append(cmd)
          elif isinstance(cmd, list):
            if len(cmd) == 0:
              pass
            else:
              shell_commands.append(cmd[0])

for cmd in shell_commands:
  for category, examples in categories.items():
    found = False
    for example in examples:
      if cmd.startswith(example):
        separated[category].append(cmd)
        found = True
        break
    if found:
      break
  else:
    uncategorized.append(cmd)

l = []
for category, cmds in separated.items():
  for cmd in cmds:
    l.append(category)

for cmd in uncategorized:
  l.append('uncategorized')

print()
print('shell command categories:')
print_collection(l)
print()
print('uncategorized:')
uncategorized.sort()
for cmd in uncategorized:
  cmd = cmd.strip()
  if cmd:
    print(cmd)
print('```')
