// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:io';

void main(List<String> args) {
  // Use `runZonedGuarded` instead of try/catch, and do it here before anything
  // else has been printed --- both because of
  // https://github.com/dart-lang/sdk/issues/54911.
  runZonedGuarded(
    () {
      mainImpl(args);
    },
    (e, _) {
      stderr.writeln("Error: $e");
    },
  );
}

const String CSI = "\x1b[";

Map<String, GitBranch> branches = {};

GitBranch getBranch(String name) {
  GitBranch? result = branches[name];
  if (result == null) {
    result = branches[name] = new GitBranch(name);
  }
  return result;
}

void mainImpl(List<String> args) {
  ProcessResult result = Process.runSync("git", [
    "branch",
    "--list",
    "--format=%(refname:short)%09%(upstream:short)",
  ], runInShell: true);
  result.stdout.split("\n").forEach(processGitBranchLine);

  result = Process.runSync("git", [
    "branch",
    "--show-current",
  ], runInShell: true);
  String currentBranchName = result.stdout;
  currentBranchName = currentBranchName.trim();
  GitBranch currentBranch = branches[currentBranchName]!;
  Set<String> involvedBranchNames = {};
  currentBranch.collectSelfAndParentNames(involvedBranchNames);
  currentBranch.collectSelfAndChildrenNames(involvedBranchNames);

  result = Process.runSync("git", [
    "branch",
    "--list",
    "--format=%(refname:short)%09%(upstream:track)",
    ...involvedBranchNames,
  ], runInShell: true);
  result.stdout.split("\n").forEach(processGitBranchTrackLine);

  int indentation = currentBranch.parent?.printSelfAndParentChain() ?? 0;

  currentBranch.printSelfAndChildren(indentation, color: true);
}

void processGitBranchLine(String gitLine) {
  if (gitLine.isEmpty) return;
  int pos = gitLine.indexOf("\t");
  String thisName = gitLine.substring(0, pos);
  String parentName = gitLine.substring(pos + 1).trim();
  GitBranch thisBranch = getBranch(thisName);
  GitBranch parentBranch = getBranch(parentName);
  parentBranch.registerChild(thisBranch);
}

void processGitBranchTrackLine(String gitLine) {
  if (gitLine.isEmpty) return;
  int pos = gitLine.indexOf("\t");
  String thisName = gitLine.substring(0, pos);
  String tracking = gitLine.substring(pos + 1).trim();
  GitBranch thisBranch = getBranch(thisName);
  thisBranch.tracking = tracking;
}

class GitBranch {
  final String name;
  GitBranch? parent;
  final List<GitBranch> children = [];
  String? tracking;

  GitBranch(this.name);

  void collectSelfAndChildrenNames(Set<String> names) {
    names.add(name);
    for (GitBranch child in children) {
      child.collectSelfAndChildrenNames(names);
    }
  }

  void collectSelfAndParentNames(Set<String> names) {
    parent?.collectSelfAndParentNames(names);
    names.add(name);
  }

  void printSelfAndChildren(int indention, {bool color = false}) {
    _printLineWithIndention(indention, color: color);
    for (GitBranch child in children) {
      child.printSelfAndChildren(indention + 1);
    }
  }

  int printSelfAndParentChain() {
    int indention = 0;
    GitBranch? parent = this.parent;
    if (parent != null) {
      indention = parent.printSelfAndParentChain();
    }
    _printLineWithIndention(indention);

    return indention + 1;
  }

  void registerChild(GitBranch child) {
    children.add(child);
    child.parent = this;
  }

  @override
  String toString() {
    return "GitBranch[$name, children = $children]";
  }

  void _printLineWithIndention(int indention, {bool color = false}) {
    stdout.write("│   " * (indention));
    stdout.write("├── ");
    if (color) {
      stdout.write("${CSI}31m");
    }
    stdout.write("$name");
    if (color) {
      stdout.write("${CSI}0m");
    }
    if (tracking != null) {
      stdout.write(" $tracking");
    }
    stdout.write("\n");
  }
}
