//! jj-specific constants
//!
//! Centralized definitions for jj command names, flags, and special values.

/// jj command binary name
pub const JJ_COMMAND: &str = "jj";

/// jj subcommands
pub mod commands {
    pub const LOG: &str = "log";
    pub const CONFIG: &str = "config";
    pub const CONFIG_GET: &str = "get";
    pub const STATUS: &str = "status";
    pub const SHOW: &str = "show";
    pub const DESCRIBE: &str = "describe";
    pub const NEW: &str = "new";
    pub const EDIT: &str = "edit";
    pub const COMMIT: &str = "commit";
    pub const UNDO: &str = "undo";
    pub const SQUASH: &str = "squash";
    pub const ABANDON: &str = "abandon";
    pub const SPLIT: &str = "split";
    pub const OP: &str = "op";
    pub const OP_LOG: &str = "log";
    pub const OP_RESTORE: &str = "restore";
    pub const BOOKMARK: &str = "bookmark";
    pub const BOOKMARK_CREATE: &str = "create";
    pub const BOOKMARK_SET: &str = "set";
    pub const BOOKMARK_DELETE: &str = "delete";
    pub const BOOKMARK_LIST: &str = "list";
    pub const BOOKMARK_TRACK: &str = "track";
    pub const BOOKMARK_UNTRACK: &str = "untrack";
    pub const BOOKMARK_RENAME: &str = "rename";
    pub const BOOKMARK_FORGET: &str = "forget";
    pub const BOOKMARK_MOVE: &str = "move";
    pub const BOOKMARK_ADVANCE: &str = "advance";
    pub const NEXT: &str = "next";
    pub const PREV: &str = "prev";
    pub const REBASE: &str = "rebase";
    pub const ABSORB: &str = "absorb";
    pub const FILE: &str = "file";
    pub const FILE_ANNOTATE: &str = "annotate";
    pub const RESOLVE: &str = "resolve";
    pub const GIT: &str = "git";
    pub const GIT_FETCH: &str = "fetch";
    pub const GIT_PUSH: &str = "push";
    pub const DUPLICATE: &str = "duplicate";
    pub const DIFFEDIT: &str = "diffedit";
    pub const RESTORE: &str = "restore";
    pub const EVOLOG: &str = "evolog";
    pub const DIFF: &str = "diff";
    pub const REVERT: &str = "revert";
    pub const SIMPLIFY_PARENTS: &str = "simplify-parents";
    pub const PARALLELIZE: &str = "parallelize";
    pub const FIX: &str = "fix";
    pub const RUN: &str = "run";
    pub const GIT_REMOTE: &str = "remote";
    pub const GIT_REMOTE_LIST: &str = "list";
    pub const TAG: &str = "tag";
    pub const TAG_LIST: &str = "list";
    pub const TAG_SET: &str = "set";
    pub const TAG_DELETE: &str = "delete";
    pub const INTERDIFF: &str = "interdiff";
    pub const BISECT: &str = "bisect";
    pub const BISECT_RUN: &str = "run";
    pub const METAEDIT: &str = "metaedit";
    pub const ARRANGE: &str = "arrange";
    pub const WORKSPACE: &str = "workspace";
    pub const WORKSPACE_LIST: &str = "list";
    pub const WORKSPACE_ADD: &str = "add";
    pub const WORKSPACE_FORGET: &str = "forget";
    pub const WORKSPACE_RENAME: &str = "rename";
}

/// jj resolve flags
pub mod resolve_flags {
    pub const LIST: &str = "--list";
    pub const TOOL: &str = "--tool";
}

/// jj command flags
pub mod flags {
    /// Disable color output for parsing (global flag, safe for all commands)
    pub const NO_COLOR: &str = "--color=never";
    /// Run without writing to the operation log (jj 0.41+, read-only callers)
    pub const NO_INTEGRATE_OPERATION: &str = "--no-integrate-operation";
    /// Force `jj fix` to format entire files even when `line-range-arg` is set (jj 0.41+)
    pub const ALL_LINES: &str = "--all-lines";
    /// Disable graph output for parsing (jj log only, NOT a global flag)
    pub const NO_GRAPH: &str = "--no-graph";
    /// Specify template
    pub const TEMPLATE: &str = "-T";
    /// Specify revision/revset
    pub const REVISION: &str = "-r";
    /// Specify repository path
    pub const REPO_PATH: &str = "-R";
    /// Specify bookmark for push
    pub const BOOKMARK_FLAG: &str = "--bookmark";
    /// List all remotes for bookmark list (jj 0.37+)
    pub const ALL_REMOTES: &str = "--all-remotes";
    /// Named push for new bookmarks (jj 0.37+): --named <bookmark>=<revision>
    pub const NAMED: &str = "--named";
    /// Rebase source (with descendants)
    pub const SOURCE: &str = "-s";
    /// Insert after target revision
    pub const INSERT_AFTER: &str = "-A";
    /// Insert before target revision
    pub const INSERT_BEFORE: &str = "-B";
    /// Dry-run mode (preview only, no actual push)
    pub const DRY_RUN: &str = "--dry-run";
    /// Diff from revision
    pub const FROM: &str = "--from";
    /// Diff to revision
    pub const TO: &str = "--to";
    /// Open editor for interactive editing (e.g., jj next --edit, jj prev --edit)
    pub const EDIT_FLAG: &str = "--edit";
    /// Open editor for describe (jj describe --editor, replaces deprecated --edit)
    pub const EDITOR_FLAG: &str = "--editor";
    /// Limit number of results
    pub const LIMIT: &str = "--limit";
    /// Reversed display order (oldest first)
    pub const REVERSED: &str = "--reversed";
    /// Push by change ID (creates automatic bookmark)
    pub const CHANGE: &str = "--change";
    /// Specify remote for push/fetch
    pub const REMOTE: &str = "--remote";
    /// Allow backwards bookmark move
    pub const ALLOW_BACKWARDS: &str = "--allow-backwards";
    /// Push all bookmarks (including new)
    pub const ALL: &str = "--all";
    /// Push tracked bookmarks only
    pub const TRACKED: &str = "--tracked";
    /// Push deleted bookmarks
    pub const DELETED: &str = "--deleted";
    /// Revert onto target revision
    pub const ONTO: &str = "--onto";
    /// Push all bookmarks on specified revisions
    pub const REVISIONS: &str = "--revisions";
    /// Git-compatible unified diff format
    pub const GIT_FORMAT: &str = "--git";
    /// Histogram diff summary
    pub const STAT: &str = "--stat";
    /// Allow pushing private commits
    pub const ALLOW_PRIVATE: &str = "--allow-private";
    /// Allow pushing commits with no description
    pub const ALLOW_EMPTY_DESC: &str = "--allow-empty-description";
    /// Fetch specific branch only
    pub const BRANCH: &str = "--branch";
    /// Rebase branch mode (short form, distinct from --branch for fetch)
    pub const BRANCH_SHORT: &str = "-b";
    /// Skip commits that become empty after rebase
    pub const SKIP_EMPTIED: &str = "--skip-emptied";
    /// Simplify parents of rebased commits (remove redundant ancestors)
    pub const SIMPLIFY_PARENTS: &str = "--simplify-parents";
}

/// Default limit for log output (no revset)
pub const DEFAULT_LOG_LIMIT: &str = "200";

/// Special jj values
pub mod special {
    /// The root change ID (all 'z' characters)
    ///
    /// In jj, the root commit has a special change ID consisting of all 'z'.
    /// This is used to identify and specially render the root in Log View.
    pub const ROOT_CHANGE_ID: &str = "zzzzzzzz";
}

/// Error detection patterns in jj output
pub mod errors {
    /// Pattern indicating not a jj repository
    pub const NOT_A_REPO: &str = "There is no jj repo";
}

// Re-export commonly used constants at module level for convenience
pub use special::ROOT_CHANGE_ID;

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_root_change_id_is_all_z() {
        assert!(ROOT_CHANGE_ID.chars().all(|c| c == 'z'));
    }

    #[test]
    fn test_root_change_id_length() {
        // jj uses 8 character short IDs by default
        assert_eq!(ROOT_CHANGE_ID.len(), 8);
    }

    #[test]
    fn test_jj_command_name() {
        assert_eq!(JJ_COMMAND, "jj");
    }

    #[test]
    fn test_no_color_flag_format() {
        // Ensure the flag is in the correct format
        assert!(flags::NO_COLOR.starts_with("--color="));
    }
}
