#!/usr/bin/env python3
import os
import argparse
import sys
#from datetime import datetime
import glob
import shutil
#import subprocess
#import time
#from rcdtype import recordtype
from dataclasses import dataclass

import montera.gutil as gutil


# Expecting files of the format BX992_____202312200600.T04
def move_daily(
    folder,
    ext='*T04',
):
    daily_list = []
    flist = sorted(glob.glob(ext, root_dir=folder))
    for f in flist:
        #print(f, f.split("_")
        date = f.split("_")[-1]
        #daily = date[4:8]    # mmdd
        prefix = f.split("_")[0]
        if prefix == 'BLDG2BD':
           prefix = 'Z3R'
        daily = os.path.join(date[2:8] + '_remote_310mm', 'data', 'gnss', prefix)     # yymmdd
        #print(f"{f=} {date=} {daily=}")
        #if daily not in daily_list:
        #    daily_list.append(daily)
        daily_dir = os.path.join(folder, daily)
        os.makedirs(daily_dir, exist_ok=True)
        print(f"move {f} to {daily}")
        #os.rename(
        #    os.path.join(folder, f),
        #    os.path.join(folder, daily, f)
        #)

    #c_file = os.path.join(folder, "comments.txt")
    #if os.path.isfile(c_file):
    #    for d in daily_list:
    #        if not os.path.isfile(os.path.join(folder, d, "comments.txt")):
    #            print(f"Copying comments.txt to {d}")
    #            shutil.copy(
    #                c_file,
    #                os.path.join(folder, d, "comments.txt")
    #                )

def move_by_device(
    folder,
    ext='*T04',
):
    dev_list = []
    flist = sorted(glob.glob(ext, root_dir=folder))
    for f in flist:
        dev = f.split("_")[0]
        if dev not in dev_list:
            dev_list.append(dev)
        dev_dir = os.path.join(folder, dev)
        os.makedirs(dev_dir, exist_ok=True)
        print(f"move {f} to {dev}")
        os.rename(
            os.path.join(folder, f),
            os.path.join(folder, dev, f)
        )

@dataclass
class t04_date:
    '''Class for using date fields of a T04 filename'''
    dev: str
    year: str
    month: str
    day: str
    hour: str
    minute: str

    def __init__(self, fname: str):
        self.fname = fname
        self.dev = fname.split("_")[0]
        date_str = fname.split("_")[1]
        self.year = date_str[0:4]
        self.month = date_str[4:6]
        self.day = date_str[6:8]
        self.hour = date_str[8:10]
        if len(date_str.split('.')[0]) > 10:
            self.minute = date_str[10:12]
        else:
            self.minute = '00'

    def get_date_matched_files(self, search_folder: str) -> list:
        f_list = []
        for dirpath, dirnames, filenames in os.walk(search_folder):
            for f in filenames:
                if not f.endswith('.T04'):
                    continue
                if f.endswith(f'{self.year}{self.month}{self.day}{self.hour}{self.minute}.T04'):
                    f_list.append(os.path.join(dirpath, f))
        return f_list


def move_by_device_montera(
    folder: str,
    base_folder: str,
    dev: str,
    ext: str='*T04',
    dryrun = True,
):
    flist = sorted(glob.glob(ext, root_dir=base_folder))
    for f in flist:
        if not f.startswith(dev):
            continue
        if not f.endswith('T04') and not f.endswith('T02'):
            continue
        fields = t04_date(f)
        print(f)
        #print('   ', fields)

        src_path = os.path.join(base_folder, f)
        #print(f'    {src_path=}')

        match_list = fields.get_date_matched_files(folder)
        #print('   ', match_list)
        days = []
        for path_match in match_list:
            sp_path = path_match.split(os.sep)
            day = sp_path[1]
            if day.startswith('_'):
                continue
            if 'data' != sp_path[2] or 'gnss' != sp_path[3]:
                print('Error: expecting FOLDER/DAY/data/gnss format')
                print(f'{path_match=}')
                sys.exit()
            if day not in days:
                days.append(day)

        copy_made = False
        if days:
            print('    days:', days)
        for day in days:
            dest_dir = os.path.join(folder, day, 'data', 'gnss', fields.dev)
            dest_path = os.path.join(dest_dir, f)
            print(f'    {src_path} -> {dest_path}')
            if not dryrun:
                print(f'    not dryrun')
                if not os.path.isfile(dest_path):
                    os.makedirs(dest_dir, exist_ok=True)
                    shutil.copy2(src_path, dest_path)
                    copy_made = True
                    if not os.path.isfile(dest_path):
                        print('Error: expecting file {dest_path}')
                        sys.exit()
                    else:
                        print(f'    found {dest_path}')
        if copy_made:
            print(f'    Removing {src_path}')
            if not dryrun:
                os.remove(src_path)
        #print(f'    Done with {f}')



# Main
# ----------------------------------------------------
def main():
    #total_start_time = datetime.now()

    parser = argparse.ArgumentParser(
        description='Move files with names like BX992_____202312200600.T04 '
        'to daily folders with names like 231222/. If a comments.txt file '
        'exists in FOLDER, then copy it to eacy of daily folders, but do not '
        'overwrite any existing comment.txt files in the dail folders. T04 '
        'files will overwrite files in the daily folders.',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
        )
    parser.add_argument('-v', '--Verbose', action='count', default=0)
    parser.add_argument(
        "-F", "--folder",
        type=str,
        default=".",
        help="TODO"
        )
    parser.add_argument(
        "--base_folder",
        type=str,
        default="_bases",
        help="TODO"
        )
    parser.add_argument(
        "--dev",
        type=str,
        default="Survey-WCO",
        help="TODO"
        )
    #parser.add_argument(
    #    '-d', '--by-device',
    #    action="store_true",
    #    help="group files by device name only"
    #    )

    debugp = parser.add_argument_group('Debug options')
    gutil.add_common_bool(debugp, 'dryrun')

    args = parser.parse_args()


    move_by_device_montera(args.folder, args.base_folder, args.dev, '*T04', args.dryrun)
    #if args.by_device:
    #    move_by_device(args.folder)
    #else:
    #    move_daily(args.folder)


if __name__ == '__main__':
    main()
