<commit_before>_ = require 'underscore'
fs = require 'fs'
Subscriber = require 'subscriber'
EventEmitter = require 'event-emitter'
RepositoryStatusTask = require 'repository-status-task'
GitUtils = nodeRequire 'git-utils'

module.exports =
class Git
  @open: (path, options) ->
    return null unless path
    try
      new Git(path, options)
    catch e
      null

  statusFlags:
    index_new: 1 << 0
    index_modified: 1 << 1
    index_deleted: 1 << 2
    index_renamed: 1 << 3
    index_typechange: 1 << 4
    working_dir_new: 1 << 7
    working_dir_modified: 1 << 8
    working_dir_delete: 1 << 9
    working_dir_typechange: 1 << 10
    ignore: 1 << 14

  statuses: null
  upstream: null
  statusTask: null

  constructor: (path, options={}) ->
    @repo = GitUtils.open(path)
    unless @repo?
      throw new Error("No Git repository found searching path: #{path}")

    @statuses = {}
    @upstream = {ahead: 0, behind: 0}

    refreshOnWindowFocus = options.refreshOnWindowFocus ? true
    if refreshOnWindowFocus
      $ = require 'jquery'
      @subscribe $(window), 'focus', =>
        @refreshIndex()
        @refreshStatus()

    project?.eachBuffer this, (buffer) =>
      bufferStatusHandler = =>
        path = buffer.getPath()
        @getPathStatus(path) if path
      @subscribe buffer, 'saved', bufferStatusHandler
      @subscribe buffer, 'reloaded', bufferStatusHandler

  getRepo: ->
    unless @repo?
      throw new Error("Repository has been destroyed")
    @repo

  refreshIndex: -> @getRepo().refreshIndex()

  getPath: ->
    @path ?= fs.absolute(@getRepo().getPath())

  destroy: ->
    if @statusTask?
      @statusTask.abort()
      @statusTask.off()
      @statusTask = null

    @repo = null
    @unsubscribe()

  getWorkingDirectory: ->
    @getRepo().getWorkingDirectory()

  getHead: ->
    @getRepo().getHead() ? ''

  getPathStatus: (path) ->
    currentPathStatus = @statuses[path] ? 0
    pathStatus = @getRepo().getStatus(@relativize(path)) ? 0
    if pathStatus > 0
      @statuses[path] = pathStatus
    else
      delete @statuses[path]
    if currentPathStatus isnt pathStatus
      @trigger 'status-changed', path, pathStatus
    pathStatus

  isPathIgnored: (path) ->
    @getRepo().isIgnored(@relativize(path))

  isStatusModified: (status=0) ->
    modifiedFlags = @statusFlags.working_dir_modified |
                    @statusFlags.working_dir_delete |
                    @statusFlags.working_dir_typechange |
                    @statusFlags.index_modified |
                    @statusFlags.index_deleted |
                    @statusFlags.index_typechange
    (status & modifiedFlags) > 0

  isPathModified: (path) ->
    @isStatusModified(@getPathStatus(path))

  isStatusNew: (status=0) ->
    newFlags = @statusFlags.working_dir_new |
               @statusFlags.index_new
    (status & newFlags) > 0

  isPathNew: (path) ->
    @isStatusNew(@getPathStatus(path))

  relativize: (path) ->
    workingDirectory = @getWorkingDirectory()
    if workingDirectory and path.indexOf("#{workingDirectory}/") is 0
      path.substring(workingDirectory.length + 1)
    else
      path

  getShortHead: ->
    @getRepo().getShortHead()

  checkoutHead: (path) ->
    headCheckedOut = @getRepo().checkoutHead(@relativize(path))
    @getPathStatus(path) if headCheckedOut
    headCheckedOut

  getDiffStats: (path) ->
    _.clone(@getRepo().getDiffStats(@relativize(path)))

  isSubmodule: (path) ->
    @getRepo().isSubmodule(@relativize(path))

  refreshStatus: ->
    if @statusTask?
      @statusTask.off()
      @statusTask.one 'task-completed', =>
        @statusTask = null
        @refreshStatus()<commit_msg>Use status helpers from git-utils module<commit_after>_ = require 'underscore'
fs = require 'fs'
Subscriber = require 'subscriber'
EventEmitter = require 'event-emitter'
RepositoryStatusTask = require 'repository-status-task'
GitUtils = nodeRequire 'git-utils'

module.exports =
class Git
  @open: (path, options) ->
    return null unless path
    try
      new Git(path, options)
    catch e
      null

  statuses: null
  upstream: null
  statusTask: null

  constructor: (path, options={}) ->
    @repo = GitUtils.open(path)
    unless @repo?
      throw new Error("No Git repository found searching path: #{path}")

    @statuses = {}
    @upstream = {ahead: 0, behind: 0}

    refreshOnWindowFocus = options.refreshOnWindowFocus ? true
    if refreshOnWindowFocus
      $ = require 'jquery'
      @subscribe $(window), 'focus', =>
        @refreshIndex()
        @refreshStatus()

    project?.eachBuffer this, (buffer) =>
      bufferStatusHandler = =>
        path = buffer.getPath()
        @getPathStatus(path) if path
      @subscribe buffer, 'saved', bufferStatusHandler
      @subscribe buffer, 'reloaded', bufferStatusHandler

  getRepo: ->
    unless @repo?
      throw new Error("Repository has been destroyed")
    @repo

  refreshIndex: -> @getRepo().refreshIndex()

  getPath: ->
    @path ?= fs.absolute(@getRepo().getPath())

  destroy: ->
    if @statusTask?
      @statusTask.abort()
      @statusTask.off()
      @statusTask = null

    @repo = null
    @unsubscribe()

  getWorkingDirectory: ->
    @getRepo().getWorkingDirectory()

  getHead: ->
    @getRepo().getHead() ? ''

  getPathStatus: (path) ->
    currentPathStatus = @statuses[path] ? 0
    pathStatus = @getRepo().getStatus(@relativize(path)) ? 0
    if pathStatus > 0
      @statuses[path] = pathStatus
    else
      delete @statuses[path]
    if currentPathStatus isnt pathStatus
      @trigger 'status-changed', path, pathStatus
    pathStatus

  isPathIgnored: (path) ->
    @getRepo().isIgnored(@relativize(path))

  isStatusModified: (status) ->
    @getRepo().isStatusModified(status)

  isPathModified: (path) ->
    @isStatusModified(@getPathStatus(path))

  isStatusNew: (status) ->
    @getRepo().isStatusNew(status)

  isPathNew: (path) ->
    @isStatusNew(@getPathStatus(path))

  relativize: (path) ->
    workingDirectory = @getWorkingDirectory()
    if workingDirectory and path.indexOf("#{workingDirectory}/") is 0
      path.substring(workingDirectory.length + 1)
    else
      path

  getShortHead: ->
    @getRepo().getShortHead()

  checkoutHead: (path) ->
    headCheckedOut = @getRepo().checkoutHead(@relativize(path))
    @getPathStatus(path) if headCheckedOut
    headCheckedOut

  getDiffStats: (path) ->
    _.clone(@getRepo().getDiffStats(@relativize(path)))

  isSubmodule: (path) ->
    @getRepo().isSubmodule(@relativize(path))

  refreshStatus: ->
    if @statusTask?
      @statusTask.off()
      @statusTask.one 'task-completed', =>
        @statusTask = null
        @refreshStatus()
{'fraction_non_alphanumeric': 0.1267605633802817, 'fraction_numerical': 0.005993407252022775, 'mean_word_length': 3.0701219512195124, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 55, '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': '7417390', 'n_tokens_mistral': 2103, 'n_tokens_neox': 2028, 'n_words': 449}