import os

from .file import generate_breadcrumbs, sanitize_file_name, tree_join
from .page import Page
from .tree import safe_join

class TreePage(Page):
    def __init__(self, out_dir, name, commit, sub_tree, repo, content_subdir):
        tree = safe_join(commit.tree, sub_tree)
        super(TreePage, self).__init__('tree.md', out_dir, os.path.join(tree_join(commit, tree.path), '_index.md'), name, content_subdir)
        self.tree = tree
        self.repo = repo
        self.commit = commit
        self.sub_tree = sub_tree

    def _generate_entries(self, nodes):
        entries = []
        for node in nodes:
            latest_commit = next(self.repo.iter_commits(self.commit, max_count=1, paths=node.path))
            name = node.name
            file_name = name
            if node.type == 'tree':
                name += '/'
                file_name = name
            else:
                file_name = sanitize_file_name(name, self.tree.blobs)
            entry = {
                'file_name': file_name,
                'name': name,
                'modified': latest_commit.committed_datetime
            }
            entries.append(entry)
        return entries

    def _get_entries(self):
        files = self._generate_entries(self.tree.blobs)
        dirs = self._generate_entries(self.tree.trees)
        files.sort(key=lambda x: x['name'])
        dirs.sort(key=lambda x: x['name'])
        return dirs + files

    def context(self):
        return {
            'breadcrumbs': generate_breadcrumbs(self.content_subdir, self.commit, self.sub_tree, self.tree.blobs),
            'content_subdir': self.content_subdir,
            'entries': self._get_entries(),
            # TODO: Make this fit the rest of the system.
            'subdir': '/'.join([self.content_subdir, tree_join(self.commit, self.tree.path)]),
            'title': self.name + ': Tree'
        }

    def build_pages(self, factory):
        visited = set()
        remaining = [self.sub_tree]
        tree_pages = []
        while remaining:
            current = remaining.pop()
            if not current in visited:
                visited.add(current)
                tree = safe_join(self.commit.tree, current)
                tree_pages.append(factory.new_tree(self.commit, tree.path, self.repo))
                for sub_tree in tree.trees:
                    remaining.append(sub_tree.path)

        return tree_pages

    def get_files(self):
        file_paths = []
        for blob in self.tree.blobs:
            file_paths.append(blob.path)

        return file_paths
