#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Functions managing the several directory names.
"""

# System modules
import shutil
from pathlib import Path

# Third-party modules
from astropy.io import fits
from astropy.time import Time

# Other templates
from ..config.constants import (DATA_FOLDER, FILE_PREFIX, FITS_EXT,
                                FITS_FOLDER, FOCUS_EXT, FOCUS_FOLDER, LOG_EXT,
                                LOG_FOLDER, dateobs, dir_type, frame_number,
                                imagetyp)

PROJECT_ROOT = Path(__file__).parent.parent.parent


def date_folder():
    """Create a date folder string based on astronomical convention
    (changes at midday UTC).
    """
    now = Time.now()
    # If current UTC hour is before midday UTC, the "observing night"
    # belongs to the previous calendar date.
    if now.datetime.hour < 12:
        folder_date_obj = now.datetime.date() - timedelta(days=1)
    else:
        folder_date_obj = now.datetime.date()
    return folder_date_obj.strftime("%Y-%m-%d")


def frame_folder(header):
    """
    Create a folder depending on the image type in FITS header
    """
    frame = header[imagetyp]
    if isinstance(frame, int):
        folder_name = dir_type[frame]
    else:
        frame_num_list = [v for k, v in frame_number.items() if k in frame]
        if not frame_num_list:
            # Fallback if frame type string is not recognized
            return "unknown_type"
        folder_name = dir_type[frame_num_list[0]]
    return folder_name


def fits_path(header, dry=False):
    """
    Create a fits file path where the file will be stored
    """

    root = PROJECT_ROOT / DATA_FOLDER / FITS_FOLDER

    date_str = date_folder()
    date_path_part = Path(date_str)

    frame_path_part = Path(frame_folder(header))
    path = root / date_path_part / frame_path_part

    if not dry:
        path.mkdir(parents=True, exist_ok=True)
    return path


def log_path(dry=False):
    """
    Returns the Path object for the log directory.
    Creates it if it doesn't exist (unless dry=True).
    """

    path = PROJECT_ROOT / DATA_FOLDER / LOG_FOLDER

    if not dry:
        path.mkdir(parents=True, exist_ok=True)

    # OARPAF.YYYY-MM-DD.foc
    outfile = f"{FILE_PREFIX}.{LOG_EXT}"
    outpath = path / outfile
    return outpath

    return outpath


def foc_path(timestamp, dry=False):
    """
    Create the focus output text file name and its path
    """

    path = PROJECT_ROOT / DATA_FOLDER / FOCUS_FOLDER

    if not dry:
        path.mkdir(parents=True, exist_ok=True)

    # OARPAF.YYYY-MM-DD.foc
    outfile = f"{FILE_PREFIX}.{timestamp}.{FOCUS_EXT}"
    outpath = path / outfile
    return outpath


def save_filename(infile_path_str):
    """
    Save a fits file in its path with an ESO-style filename.
    """

    inpath = Path(infile_path_str)
    header = fits.getheader(inpath)

    # '2021-12-28T20:09:56.163'
    date_obs_str = header[dateobs]  # DATE-OBS from FITS header
    name_for_file = Time(date_obs_str).isot

    outfile_name = f"{FILE_PREFIX}.{name_for_file}.{FITS_EXT}"
    outfile = Path(outfile_name)

    outdir = fits_path(header)  # This already creates the directory
    outpath = outdir / outfile

    shutil.copy2(inpath, outpath)
    return str(outpath)
