"""Command-line interface for the text analyzer.""" import argparse import json import sys from pathlib import Path from typing import Final from text_analyzer.core import TextStatistics, analyze_file DEFAULT_TOP: Final[int] = 10 DEFAULT_MIN_LEN: Final[int] = 1 DEFAULT_ENCODING: Final[str] = "utf-8" def build_parser() -> argparse.ArgumentParser: """Build command-line parser.""" parser = argparse.ArgumentParser( prog="text-analyzer", description="Analyze a text file.", ) parser.add_argument( "path", type=Path, help="Path to the text file.", ) parser.add_argument( "--top", type=int, default=DEFAULT_TOP, help="Number of most frequent words.", ) parser.add_argument( "--min-len", type=int, default=DEFAULT_MIN_LEN, help="Minimum word length.", ) parser.add_argument( "--format", choices=("text", "json"), default="text", help="Output format.", ) parser.add_argument( "--encoding", default=DEFAULT_ENCODING, help="Input file encoding.", ) return parser def format_text(statistics: TextStatistics) -> str: """Format statistics as text.""" lines = [ f"Lines: {statistics.lines}", f"Words: {statistics.words}", f"Characters: {statistics.characters}", "Top words:", ] if statistics.top_words: for word, count in statistics.top_words: lines.append(f" {word}: {count}") else: lines.append(" No words found.") return "\n".join(lines) def format_json(statistics: TextStatistics) -> str: """Format statistics as JSON.""" data = { "lines": statistics.lines, "words": statistics.words, "characters": statistics.characters, "top_words": [ { "word": word, "count": count, } for word, count in statistics.top_words ], } return json.dumps( data, ensure_ascii=True, indent=2, ) def main() -> int: """Run CLI application.""" parser = build_parser() args = parser.parse_args() if args.top < 0: print( "Error: --top must be non-negative.", file=sys.stderr, ) return 2 if args.min_len < 1: print( "Error: --min-len must be at least 1.", file=sys.stderr, ) return 2 try: statistics = analyze_file( args.path, top=args.top, min_len=args.min_len, encoding=args.encoding, ) except FileNotFoundError: print( f"Error: file not found: {args.path}", file=sys.stderr, ) return 1 except UnicodeError: print( f"Error: cannot decode file using encoding: {args.encoding}", file=sys.stderr, ) return 1 except OSError as exc: print( f"Error: cannot read file: {exc}", file=sys.stderr, ) return 1 except ValueError as exc: print( f"Error: {exc}", file=sys.stderr, ) return 2 if args.format == "json": print(format_json(statistics)) else: print(format_text(statistics)) return 0 if __name__ == "__main__": raise SystemExit(main())