#!/usr/bin/env python
from concurrent.futures import ThreadPoolExecutor
from functools import partial
import os.path
import os
import sys
from typing import Iterable
from urllib.request import urlopen
import ftplib
import pysftp
import shutil
from rich import print
import requests

from rich.progress import (
    BarColumn,
    DownloadColumn,
    TextColumn,
    TransferSpeedColumn,
    TimeRemainingColumn,
    Progress,
    TaskID,
)

progress = Progress(
    TextColumn("[bold blue]{task.fields[filename]}", justify="right"),
    BarColumn(bar_width=None),
    "[progress.percentage]{task.percentage:>3.1f}%",
    "•",
    DownloadColumn(),
    "•",
    TransferSpeedColumn(),
    "•",
    TimeRemainingColumn(),
)


def copy_url(task_id: TaskID, url: str, path: str) -> None:
    """Copy data from a url to a local file."""
    response = urlopen(url)
    # This will break if the response doesn't contain content length
    progress.update(task_id, total=int(response.info()["Content-length"]))
    inventario.write(path + ":" + response.info()["Content-length"] + "\n")
    inventario.flush()
    with open(path, "wb") as dest_file:
        progress.start_task(task_id)
        for data in iter(partial(response.read, 32768), b""):
            dest_file.write(data)
            progress.update(task_id, advance=len(data))


def copy_url_secure(task_id: TaskID, url: str, path: str) -> None:
    """Copy data from a url to a local file."""
    site = "safmil.ipma.pt"
    cwd = 'OperationalChain/LSASAF_Products/FRP-PIXEL/'

    # ftp.login("buinpe", "buinpe890")

    srv = pysftp.Connection(host=site, username="rgklongo", password="F109tq21")
    srv.chdir(cwd)
    status = srv.stat(url)
    tamanho = status.st_size
    inventario.write(path + ":{0:012d}\n".format(tamanho))
    inventario.flush()
    progress.update(task_id, total=int(tamanho))
    srv.get(url, path)
    fsize = os.path.getsize(path)
    progress.update(task_id, advance=tamanho)
    srv.close()


def copy_url_wget(task_id: TaskID, url: str, path: str) -> None:
    """Copy data from a url to a local file."""
    response = requests.get(url, stream=True)
    #print("Inside wget:",task_id, response.headers.get('content-length'))
    progress.update(task_id, total=int(response.headers.get('content-length')))
    #print("Passei pelo update!")
    #inventario.write(path + ":" + response.info()["Content-length"] + "\n")
    #print("Passei pelo inventário!")
    #inventario.flush()
    #print("Dest>:",path)
    #print("")
    #sys.stdout.flush()
    #print(task_id,path)
    with open(path, "wb") as dest_file:
        #print(dest_file)
        sys.stdout.flush()
        progress.start_task(task_id)
        downloaded = 0
        total = int(response.headers.get('content-length'))
        for data in response.iter_content(32768):
            #print("No laço!")
            downloaded += len(data)
            dest_file.write(data)
            progress.update(task_id, advance=len(data))
            sys.stdout.flush()

def download(urls: Iterable[str], dest_dir: str):
    """Download multiple files to the given directory."""
    with progress:
        with ThreadPoolExecutor(max_workers=8) as pool:
            for url in urls:
                filename = url.split("/")[-1]
                dest_path = os.path.join(dest_dir, filename)
                task_id = progress.add_task("download", filename=filename, start=False)
                pool.submit(copy_url, task_id, url, dest_path)

def download_wget(urls: Iterable[str], dest_dir: str):
    """Download multiple files to the given directory."""
    with progress:
        with ThreadPoolExecutor(max_workers=8) as pool:
            for url in urls:
                filename = url.split("/")[-1]
                dest_path = os.path.join(dest_dir, filename)
                task_id = progress.add_task("download", filename=filename, start=False)
                #print(task_id,dest_path)
                pool.submit(copy_url_wget, task_id, url, dest_path)



def download_secure(urls: Iterable[str], dest_dir: str):
    """Download multiple files to the given directory."""
    with progress:
        with ThreadPoolExecutor(max_workers=8) as pool:
            for url in urls:
                filename = url
                dest_path = os.path.join(dest_dir, filename)
                task_id = progress.add_task("download", filename=filename, start=False)
                # print(task_id)
                # print(url)
                # print(dest_path)
                # print(srv)
                pool.submit(copy_url_secure, task_id, url, dest_path)


if __name__ == "__main__":
    if sys.argv[1:]:
        year = int(sys.argv[1])
        month = int(sys.argv[2])
        day = int(sys.argv[3])
        viirs = sys.argv[4]
        ecmwf = sys.argv[5]
        inpe = sys.argv[6]
        meteosat = sys.argv[7]
        ncep = sys.argv[8]
        geos = sys.argv[9]

        if year > 2021:
            print("Ano errado!")
            sys.exit(0)
        if month > 12 or month < 1:
            print("Mês errado!")
            sys.exit(0)
        if day > 31 or day < 1:
            print("Dia errado!")
            sys.exit(0)
        if viirs != 'S' and viirs != 's' and viirs != 'N' and viirs != 'n':
            print("viirs (arg=4) deve ser S ou N!")
            sys.exit(0)
        if ecmwf != 'S' and ecmwf != 's' and ecmwf != 'N' and ecmwf != 'n':
            print("ecmwf (arg=5) deve ser S ou N!")
            sys.exit(0)
        if inpe != 'S' and inpe != 's' and inpe != 'N' and inpe != 'n':
            print("inpe (arg=6) deve ser S ou N!")
            sys.exit(0)
        if meteosat != 'S' and meteosat != 's' and meteosat != 'N' and meteosat != 'n':
            print("meteosat (arg=7) deve ser S ou N!")
            sys.exit(0)
        if ncep != 'S' and ncep != 's' and ncep != 'N' and ncep != 'n':
            print("ncep (arg=8) deve ser S ou N!")
            sys.exit(0)
        if geos != 'S' and geos != 's' and geos != 'N' and geos != 'n':
            print("umid (arg=9) deve ser S ou N!")
            sys.exit(0)
        dia_para_baixar = "{0:04d}{1:02d}{2:02d}".format(year, month, day)
        # print(dia_para_baixar)
    else:
        print("Usage:\n\tpython baixa.py YYYY MM DD VIIRS ECMWF INPE METEOSAT NCEP UMID")
        print("      \n\t                  |   | |    |     |     |     |       |    |")
        print("      \n\t                  |   | |    |     |     |     |       |    +-> Soil Moisture GEOS5 [s/n]")
        print("      \n\t                  |   | |    |     |     |     |       +------> IC from NCEP/GFS [s/n]")
        print("      \n\t                  |   | |    |     |     |     +--------------> Meteosat Fire Prod. [s/n]")
        print("      \n\t                  |   | |    |     |     +--------------------> INPE/DSA Fire Prod. [s/n]")
        print("      \n\t                  |   | |    |     +--------------------------> CAMS Fire Prod. [s/n]")
        print("      \n\t                  |   | |    +--------------------------------> VIIRS Fire Prod. [s/n]")
        print("      \n\t                  |   | +-------------------------------------> Day")
        print("      \n\t                  |   +---------------------------------------> Month")
        print("      \n\t                  +-------------------------------------------> Year")
        print("\n\n")
        print("Example:\n")
        print("python baixa.py 2021 01 15 s s s s s n\n\n")
        sys.exit()

        print("")
    print("[bold green] ____  ____      _    __  __ ____  [/bold green]")
    print("[bold green]| __ )|  _ \    / \  |  \/  / ___| [/bold green]")
    print("[bold green]|  _ \| |_) |  / _ \ | |\/| \___ \ [/bold green]")
    print("[bold green]| |_) |  _ <  / ___ \| |  | |___) |[/bold green]")
    print("[bold green]|____/|_| \_\/_/   \_\_|  |_|____/ [/bold green]")
    print("[bold green]    PRE - PREP - Baixa Dados [/bold green]")
    print("Rev 1.0 - e-mail: luiz.rodrigues@inpe.br")
    print("Author: Luiz Flávio Rodrigues INPE:copyright:")
    print("")
    print("")

    inventario = open("inventario" + dia_para_baixar + ".dat", "w")
    inventario.write("{0:1s} {1:1s} {2:1s} {3:1s}\n".format(viirs, ecmwf, inpe, meteosat))



    if geos == "s" or geos == "S":
        site = "https://portal.nccs.nasa.gov/datashare/gmao/geos-fp/das/"
        cwd = "Y{0:04d}/M{1:02d}/D{2:02d}/".format(year,month,day)
        out = '/share/bramsrd/dist/BRAMS/data/GEOS/' + dia_para_baixar + '/'


        file_list = []
        file_list.append(site + cwd + "GEOS.fp.asm.tavg1_2d_lnd_Nx."+dia_para_baixar+"_0030.V01.nc4")
        file_list.append(site + cwd + "GEOS.fp.asm.tavg1_2d_ocn_Nx."+dia_para_baixar+"_0030.V01.nc4")

        download_wget(file_list, out)


    if ncep == "s" or ncep == "S":
        site = "https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/"
        cwd = 'gfs.' + dia_para_baixar + '/00/'
        out = '/share/bramsrd/dist/BRAMS/data/GFS/' + dia_para_baixar + '/'


        file_list = []
        for h in range(0,126, 6):
            file_list.append(site + cwd + "gfs.t00z.pgrb2.0p25.f{0:03d}".format(h))

        download_wget(file_list, out)
        sys.exit()

    if viirs == "s" or viirs == "S":
        site = "ftp.star.nesdis.noaa.gov"
        cwd = '/pub/smcd/tsidulko/HRRR/' + dia_para_baixar + '/'
        out = '/share/bramsrd/dist/BRAMS/data/EMISSIONS/VIIRS/' + dia_para_baixar + '/'

        if os.path.isdir(out):
            print("O diretório " + out + " já existe!")
        else:
            os.mkdir(out)

        ftp = ftplib.FTP(site)
        ftp.login("anonymous", "lufla")
        ftp.cwd(cwd)
        data = []
        ftp.dir(data.append)
        ftp.quit()

        file_list = []
        for d in data:
            tipo = d.split()[8].split("_")[2]
            if tipo == 'npp':
                file_list.append("ftp://" + site + cwd + d.split()[8])

        download(file_list, out)

    if ecmwf == 'S' or ecmwf == 's':
        site = "geoland2.meteo.pt"
        cwd = '/GOESE/'
        out = '/share/bramsrd/dist/BRAMS/data/EMISSIONS/GOES-ECMWF/' + dia_para_baixar + '/'

        if os.path.isdir(out):
            print("O diretório " + out + " já existe!")
        else:
            os.mkdir(out)

        ftp = ftplib.FTP(site)
        ftp.login("frp_public", "frp")
        ftp.cwd(cwd)
        data = []
        ftp.dir(data.append)
        ftp.quit()

        file_list = []
        for d in data:
            nome = d.split()[8]
            tipo = nome.split("-")[2]
            dia = nome.split("-")[3].split(".")[0].split("_")[1][0:8]
            if tipo == "ListProduct_GOESE" and dia == dia_para_baixar:
                file_list.append("ftp://frp_public:frp@" + site + cwd + nome)

        download(file_list, out)

    if inpe == 'S' or inpe == 's':
        site = "ftp-queimadas.dgi.inpe.br"
        cwd = '/focos24h/'
        out = '/share/bramsrd/dist/BRAMS/data/EMISSIONS/DSA/'

        ftp = ftplib.FTP(site)
        ftp.login("cptec_focos", "CP18tec")
        ftp.cwd(cwd)
        data = []
        ftp.dir(data.append)
        ftp.quit()

        file_list = []
        for d in data:
            nome = d.split()[8]
            dia = nome.split("_")[2].split(".")[0]
            if dia == dia_para_baixar:
                file_list.append("ftp://cptec_focos:CP18tec@" + site + cwd + nome)

        download(file_list, out)
        shutil.move(out + "focosINPE_24H_" + dia_para_baixar + ".txt", out + "Focos" + dia_para_baixar + ".txt")

    if meteosat == 'S' or meteosat == 's':
        site = "safmil.ipma.pt"
        cwd = 'OperationalChain/LSASAF_Products/FRP-PIXEL/'
        out = '/share/bramsrd/dist/BRAMS/data/EMISSIONS/METEOSAT/{0:04d}/{1:02d}/'.format(year, month)
        ydir = '/share/bramsrd/dist/BRAMS/data/EMISSIONS/METEOSAT/{0:04d}'.format(year)

        if not os.path.isdir(ydir):
            os.mkdir(ydir)

        if os.path.isdir(out):
            print("O diretório " + out + " já existe!")
        else:
            os.mkdir(out)

        srv = pysftp.Connection(host=site, username="rgklongo", password="F109tq21")
        srv.chdir(cwd)
        data = srv.listdir()
        file_name = []

        for d in data:
            tipo = d.split("-")[2]
            dia = d.split("-")[3].split(".")[0].split("_")[1][0:8]
            if tipo == 'ListProduct_MSG' and dia == dia_para_baixar:
                file_name.append(d)

        srv.close()
        download_secure(file_name, out)

    inventario.close()

    inventario = open("inventario" + dia_para_baixar + ".dat", "r")
    datainfo = open("dataInfo" + dia_para_baixar + ".dat", "w")
    linhas = inventario.readlines()
    first = True
    for linha in linhas:
        if first:
            first = False
            continue
        campos = linha.split(":")
        file_name = campos[0]
        if file_name == '/share/bramsrd/dist/BRAMS/data/EMISSIONS/DSA/focosINPE_24H_' + dia_para_baixar + '.txt':
            file_name = '/share/bramsrd/dist/BRAMS/data/EMISSIONS/DSA/Focos' + dia_para_baixar + '.txt'
        tamanho = int(campos[1])
        file_size = os.path.getsize(file_name)
        datainfo.write(file_name)
        datainfo.write("|{0:12d}|{1:12d}|".format(tamanho, file_size))
        if tamanho == file_size:
            datainfo.write("OK\n")
        else:
            datainfo.write("**\n")

    datainfo.close()
    inventario.close()
