<commit_before>library pubviz;

import 'dart:async';
import 'dart:io';
import 'package:yaml/yaml.dart';
import 'package:path/path.dart' as pathos;
import 'package:unmodifiable_collection/unmodifiable_collection.dart';

class VizRoot {
  final VizPackage root;
  final Map<String, VizPackage> packages;

  VizRoot._(this.root, Map<String, VizPackage> packages):
    this.packages = new UnmodifiableMapView(packages);

  static Future<VizRoot> forDirectory(String path) {
    return VizPackage.forDirectory(path)
        .then((VizPackage root) {

          return _getReferencedPackages(path)
              .then((packages) {
                assert(packages.containsKey(root.name));

                // want to make sure that the root note instance is the same
                // as the instance in the packages collection
                root = packages[root.name];

                return new VizRoot._(root, packages);
              });
        });
  }


  static Future<Map<String, String>> _getPackageMap(String path) {
    var packagePath = pathos.join(path, 'packages');
    var packageDir = new Directory(packagePath);

    var dirs = new Map<String, String>();

    var map = new Map<String, String>();

    return packageDir.list(recursive: false, followLinks: false)
        .toList()
        .then((List<Link> links) {
          return Future.forEach(links, (link) {
            return link.target()
                .then((String targetPath) {
                  var linkName = pathos.basename(link.path);

                  if(pathos.isRelative(targetPath)) {
                    targetPath = pathos.join(packagePath, targetPath);
                    targetPath = pathos.normalize(targetPath);
                  }

                  assert(pathos.isAbsolute(targetPath));
                  assert(pathos.basename(targetPath) == 'lib');

                  targetPath = pathos.dirname(targetPath);

                  assert(!map.containsKey(linkName));
                  assert(!map.containsValue(targetPath));

                  map[linkName] = targetPath;
                });
          });
        })
        .then((_) => map);
  }

  static Future<Map<String, VizPackage>> _getReferencedPackages(String path) {
    var set = new Map<String, VizPackage>();

    return _getPackageMap(path)
        .then((Map<String, String> map) {

          return Future.forEach(map.keys, (String packageName) {
            var subPath = map[packageName];
            return VizPackage.forDirectory(subPath)
                .then((VizPackage vp) {
                  assert(vp.name == packageName);

                  assert(!set.containsKey(vp.name));
                  assert(!set.containsValue(vp));
                  set[vp.name] = vp;
                });
          });
        })
        .then((_) => set);
  }



  String toDot() {
    _update();

    var sink = new StringBuffer();<commit_msg>local var tweak<commit_after>library pubviz;

import 'dart:async';
import 'dart:io';
import 'package:yaml/yaml.dart';
import 'package:path/path.dart' as pathos;
import 'package:unmodifiable_collection/unmodifiable_collection.dart';

class VizRoot {
  final VizPackage root;
  final Map<String, VizPackage> packages;

  VizRoot._(this.root, Map<String, VizPackage> packages):
    this.packages = new UnmodifiableMapView(packages);

  static Future<VizRoot> forDirectory(String path) {
    return VizPackage.forDirectory(path)
        .then((VizPackage root) {

          return _getReferencedPackages(path)
              .then((packages) {
                assert(packages.containsKey(root.name));

                // want to make sure that the root note instance is the same
                // as the instance in the packages collection
                root = packages[root.name];

                return new VizRoot._(root, packages);
              });
        });
  }


  static Future<Map<String, String>> _getPackageMap(String path) {
    var packagePath = pathos.join(path, 'packages');
    var packageDir = new Directory(packagePath);

    var dirs = new Map<String, String>();

    var map = new Map<String, String>();

    return packageDir.list(recursive: false, followLinks: false)
        .toList()
        .then((List<Link> links) {
          return Future.forEach(links, (link) {
            return link.target()
                .then((String targetPath) {
                  var linkName = pathos.basename(link.path);

                  if(pathos.isRelative(targetPath)) {
                    targetPath = pathos.join(packagePath, targetPath);
                    targetPath = pathos.normalize(targetPath);
                  }

                  assert(pathos.isAbsolute(targetPath));
                  assert(pathos.basename(targetPath) == 'lib');

                  targetPath = pathos.dirname(targetPath);

                  assert(!map.containsKey(linkName));
                  assert(!map.containsValue(targetPath));

                  map[linkName] = targetPath;
                });
          });
        })
        .then((_) => map);
  }

  static Future<Map<String, VizPackage>> _getReferencedPackages(String path) {
    var packs = new Map<String, VizPackage>();

    return _getPackageMap(path)
        .then((Map<String, String> map) {

          return Future.forEach(map.keys, (String packageName) {
            var subPath = map[packageName];
            return VizPackage.forDirectory(subPath)
                .then((VizPackage vp) {
                  assert(vp.name == packageName);

                  assert(!packs.containsKey(vp.name));
                  assert(!packs.containsValue(vp));
                  packs[vp.name] = vp;
                });
          });
        })
        .then((_) => packs);
  }



  String toDot() {
    _update();

    var sink = new StringBuffer();
{'fraction_non_alphanumeric': 0.11681598897312198, 'fraction_numerical': 0.0, 'mean_word_length': 2.0376766091051803, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2919881', 'n_tokens_mistral': 1663, 'n_tokens_neox': 1557, 'n_words': 333}