"""Argument parser for the telomore tool."""

import argparse
from argparse import Namespace
import logging
import sys

from telomore._version import __version__


def get_args() -> Namespace:
    r"""
    Parse and validate command-line arguments for Telomore.

    Defines the command-line interface for Telomore, including all required
    and optional arguments. Validates mode-specific requirements and provides
    helpful error messages.

    Returns
    -------
    argparse.Namespace
        Parsed arguments with attributes:
        - mode : str - Sequencing platform ('nanopore' or 'illumina')
        - reference : str - Path to reference genome FASTA
        - single : str or None - Nanopore FASTQ file (required if mode='nanopore')
        - read1 : str or None - Illumina R1 FASTQ (required if mode='illumina')
        - read2 : str or None - Illumina R2 FASTQ (required if mode='illumina')
        - threads : int - Number of threads (default: 1)
        - keep : bool - Retain intermediate files (default: False)
        - quiet : bool - Suppress console output (default: False)
        - coverage_threshold : int or None - Coverage cutoff for trimming
        - quality_threshold : int or None - Quality score cutoff for trimming

    Raises
    ------
    SystemExit
        If no arguments provided, required arguments missing, or mode-specific
        validation fails. Prints help message and exits with code 1.

    Notes
    -----
    Mode-specific validation:
    - nanopore mode requires --single argument
    - illumina mode requires both --read1 and --read2 arguments

    Threshold defaults (applied in main workflow if not specified):
    - Nanopore: coverage=5, quality=10
    - Illumina: coverage=1, quality=30

    Examples
    --------
    Nanopore mode:
        telomore --mode nanopore --single reads.fq.gz --reference genome.fa -t 8

    Illumina mode:
        telomore --mode illumina --read1 R1.fq.gz --read2 R2.fq.gz \\
                 --reference genome.fa -t 8 --coverage_threshold 2
    """
    parser = argparse.ArgumentParser(
        description="""Telomore: A tool to recover potential telomeric sequences from Streptomyces genomes.

This tool processes sequencing data from Oxford Nanopore or Illumina platforms to extend assemblies and generate QC reports.

INPUT:
- For Nanopore mode (--mode=nanopore): Provide a single gzipped FASTQ file using --single.
- For Illumina mode (--mode=illumina): Provide two gzipped FASTQ files using --read1 and --read2.
- A reference genome file in FASTA format is required for both modes (--reference).

OUTPUT:
- Extended assembly written to basename.02.trimmed.fasta (basename is the name of the input file without the extension).
- QC reports saved in a folder named basename_seqtype_QC.
- Logs are written to telomore.log and basename.seqtype.cons.log.txt. in basename_seqtyope_QC.

OPTIONS:
- Specify the number of threads to use with --threads (default: 1).
- Use --keep to retain intermediate files (default: False).
- Use --quiet to suppress console logging.

EXAMPLES:
1. Nanopore mode:
   telomore --mode=nanopore --single reads.fastq.gz --reference genome.fasta -t 8

2. Illumina mode:
   telomore --mode=illumina --read1 read1.fastq.gz --read2 read2.fastq.gz --reference genome.fasta -t 8
""",
        formatter_class=argparse.RawTextHelpFormatter,
    )

    parser.add_argument(
        '-v',
        '--version',
        action='version',
        version=f'telomore {__version__}',
        help='Show version number and exit',
    )

    parser.add_argument(
        '-m',
        '--mode',
        choices=['nanopore', 'illumina'],
        required=True,
        help="""Choose which mode to run.
        --mode=nanopore takes a single read-file, specified using --single
        --mode=illumina-mode takes two read-files specified using --read1 and --read2""",
    )
    parser.add_argument(
        '--single',
        type=str,
        help='Path to a single gzipped nanopore fastq-file',
    )
    parser.add_argument(
        '--read1',
        type=str,
        help='Path to gzipped illumina read1 fastq-file',
    )
    parser.add_argument(
        '--read2',
        type=str,
        help='Path to gzipped illumina read2 fastq-file',
    )
    parser.add_argument(
        '-r',
        '--reference',
        type=str,
        required=True,
        help='Path to reference file (.fasta, .fna, or .fa)',
    )
    parser.add_argument(
        '-t', '--threads', type=int, default=1, help='Threads to use. Default is 1'
    )
    parser.add_argument(
        '-k',
        '--keep',
        action='store_true',
        help='Flag to keep intermediate files. Default is False',
    )
    parser.add_argument(
        '-q', '--quiet', action='store_true', help='Set logging to quiet.'
    )
    parser.add_argument(
        '--coverage_threshold',
        type=int,
        help='Coverage threshold for consensus trimming. Default is coverage=5 for nanopore and coverage=1 for Illumina.',
    )
    parser.add_argument(
        '--quality_threshold',
        type=int,
        help='Quality threshold for consensus trimming. Default is q_score=10 for nanopore and q_score=30 for illumina.',
    )

    # Check if no arguments were provided
    if len(sys.argv) == 1:
        parser.print_help(sys.stderr)
        sys.exit(1)

    args = parser.parse_args()

    if args.mode == 'illumina':
        if not (args.read1 and args.read2):
            parser.error(
                'Illumina mode requires two FASTQ files, specified by --read1 and --read2'
            )
    elif args.mode == 'nanopore':
        if not args.single:
            parser.error(
                'Nanopore mode takes one collected FASTQ file, specified by --single'
            )
    return args


def setup_logging(log_file: str = 'telomore.log', quiet: bool = False) -> None:
    """
    Configure logging for Telomore with file and console output.

    Sets up Python's logging system to write to both a log file and console
    (unless quiet mode is enabled). Uses INFO level logging with timestamps.

    Parameters
    ----------
    log_file : str, default='telomore.log'
        Path to log file where all messages will be written
    quiet : bool, default=False
        If True, suppress console output (file logging still occurs)

    Returns
    -------
    None
        Configures the global logging system

    Notes
    -----
    Log format: '%(asctime)s - %(message)s'
    Log level: INFO (captures informational messages, warnings, and errors)

    When quiet=False, logs appear in both:
    - Console (via StreamHandler to stdout)
    - File (via FileHandler to log_file)

    When quiet=True, logs only appear in:
    - File (via FileHandler to log_file)

    This allows users to suppress verbose console output while maintaining
    a complete log file for debugging and reproducibility.
    """
    if quiet is True:
        handlers_to_use = [
            logging.FileHandler(log_file),  # Log file
        ]
    else:
        handlers_to_use = [
            logging.FileHandler(log_file),  # Log file
            logging.StreamHandler(sys.stdout),  # Print to console
        ]
    logging.basicConfig(
        level=logging.INFO, format='%(asctime)s - %(message)s', handlers=handlers_to_use
    )


if __name__ == '__main__':
    get_args()
