#!/usr/bin/env python3
# getfactormodels: A Python package to retrieve financial factor model data.
# Copyright (C) 2025-2026 S. Martin <x512@pm.me>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
import argparse
import logging
import sys
import textwrap
from importlib.metadata import PackageNotFoundError, version


def _get_version():
    """Avoids importing __init__ for the ver. no."""
    try:
        return version("getfactormodels")
    except PackageNotFoundError:
        return "unknown"


def _cli_list_regions():
    """Helper to display regions and exit."""
    from getfactormodels.models.aqr_models import _AQRModel
    from getfactormodels.models.fama_french import FamaFrenchFactors
    
    print(f"\nFAMA-FRENCH MODELS:\n  {textwrap.fill(', '.join(FamaFrenchFactors.list_regions()), width=70)}")
    print(f"\nAQR MODELS:\n  {textwrap.fill(', '.join(_AQRModel.list_regions()), width=70)}")
    print("\n  Note: accepts aliases 'us', 'jpn', 'uk', and 'ger'.")
    sys.exit(0)


def parse_args() -> argparse.Namespace:
    """CLI arg parser for getfactormodels."""
    parser = argparse.ArgumentParser(
        prog='getfactormodels',
        description='Download datasets for various factor models.',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog='''Example usage:
    getfactormodels --model ff3 --frequency m
    getfactormodels -m liquidity -f m --start 2000-01-01 --end 2009-12-31
    getfactormodels -m 5 -f m -e 2009-12-31 --extract SMB RF -o '~/file.csv'
    getfactormodels -m Carhart -f d -s 2000-01-01 -x MOM -o file
    getfactormodels -m hml_devil --region jpn
        ''', 
    )

    parser.add_argument('-v', '--version', action='version', version=f'getfactormodels {_get_version()}')
    parser.add_argument('-q', '--quiet', action='store_true', help='Suppress output to console.')

    parser.add_argument('-m', '--model', 
                        nargs="+", # new: multiple models. 
                        metavar="MODEL", help="the model to use, e.g., 'ff3', 'q'."
                        " Accepts 3, 4, 5, 6 in place of ff3, carhart, ff5, ff6.")

    parser.add_argument('-f', '--frequency', type=str, default='m',
                        choices=['d', 'w', 'w2w', 'm', 'q', 'y'], metavar="FREQ",
                        help="Data frequency (default: 'm'). Note: 'w2w' (Wed-to-Wed) is "
                        "only available for q-factors.")

    parser.add_argument('-s', '--start', required=False, metavar="YYYY-MM-DD",
                        help='the start date.')

    parser.add_argument('-e', '--end', required=False, metavar="YYYY-MM-DD",
                        help='the end date.')

    parser.add_argument('-o', '--output', type=str, required=False, default=None, metavar="PATH",
                        help='filename/filepath to save the data to.')

    parser.add_argument('-d', '--drop', nargs='+', metavar='FACTOR', 
                        help="drop specific factor(s) from a model.")

    parser.add_argument('-x', '--extract', nargs='+', metavar="FACTOR",
                        help='extract specific factor(s) from a model.')

    parser.add_argument('-r', '--region', dest='region', metavar='REGION',
                        help="Region or country code for AQR/FF models. "
                        "Use `--list-regions` to see all valid regions.")
    parser.add_argument('--list-regions', action='store_true', help="show all supported regions and exit")
    parser.add_argument('--verbose', action='store_true', help="verbose output (set log to debug)")
    
    #parser.add_argument('--industry-portfolios', type=int, action=???, 
    #                    help="Get Fama-French returns by industry. One of: 5, 10, 12, 20, 30, 38, 49") 
    
    args = parser.parse_args()

    if args.verbose:
        logging.getLogger("getfactormodels").setLevel(logging.DEBUG)
    else:
        logging.getLogger("getfactormodels").setLevel(logging.WARNING)

    return args
