import gzip
from hashlib import md5
from io import BytesIO

import requests
from fastapi import FastAPI
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from cameo_claw.cameo_claw import it_chunk

from pydantic import BaseModel
import polars as pl

app = FastAPI()
app.add_middleware(CORSMiddleware,
                   allow_origins=['*'],
                   allow_credentials=True,
                   allow_methods=['*'],
                   allow_headers=['*'])


class ItemUrlFilter(BaseModel):
    lst_url: list = [
        'https://cameo-claw-data.vercel.app/device_21152332479_daily_2022-03-30.csv',
        'https://cameo-claw-data.vercel.app/device_21152332479_daily_2022-03-31.csv']
    target_directory: str = './data/topic_filter/'
    lst_distinct_column: list = ['deviceId', 'localTime', 'sensorId']
    lst_column_match: list = [
        ['sensorId', 'pm2_5'],
        ['sensorId', 'voc']
    ]
    sort_column: str = 'localTime'


def it_streaming(i: ItemUrlFilter):
    yield write_csv_header_to_gz(i)
    for int_progress, bytes1 in it_chunk(
            i.lst_url, i.target_directory, i.lst_distinct_column, i.lst_column_match, i.sort_column):
        if bytes1:
            yield bytes1
        else:
            continue


def write_csv_header_to_gz(i):
    r = requests.get(i.lst_url[0], verify=False)
    df = pl.read_csv(r.content)
    bytesio_gz = BytesIO()
    with gzip.open(bytesio_gz, 'wb') as f:
        f.write((','.join(df.columns) + '\n').encode('utf-8'))
    return bytesio_gz.getvalue()


dic_item_url_filter = {}


@app.post("/api/streaming_post/")
def streaming_post(i: ItemUrlFilter):
    md5_hex = md5(str(i).encode()).hexdigest()
    dic_item_url_filter[md5_hex] = i
    return md5_hex


@app.get("/api/streaming_get/")
def streaming_get(md5_hex):
    dic = {'content-disposition': f"attachment; filename*=utf-8''all.csv.gz"}
    return StreamingResponse(it_streaming(dic_item_url_filter[md5_hex]), headers=dic)


def server(host='0.0.0.0', int_port=20419):
    uvicorn.run("cameo_claw.streaming:app", host=host, port=int_port, reload=False, debug=False, workers=1)
