import sys
import glob
import requests
import os
import json
import time
import shutil
import dotenv

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from preprocessor.cloud import Cloud

dotenv.load_dotenv(r'C:\Users\Z4G4\Documents\GitHub\cloud\api\src\fabricator\.env')

authApiUrl = os.getenv('BIGSCREEN_API_URL')
adminApiUrl = os.getenv('BIGSCREEN_ADMIN_API_URL')
apiBearerToken = os.getenv('FAB_API_KEY')
email = os.getenv('FAB_EMAIL')
password = os.getenv('FAB_PASSWORD')
fusion360ApiKey = os.getenv('FUSION360_API_Key')

PROCESS_DIR_PATH = os.getenv('FUSION_PROCESS_DIR_PATH')
FUSIONS_PRODUCTION_FOLDER = os.getenv('FUSIONS_PRODUCTION_FOLDER')


headers = {
  "Content-Type": "application/json",
  "Authorization": f"Bearer {fusion360ApiKey}"
}



def download_model(output_dir):
    r = requests.get(f"{adminApiUrl}/fusion/next", headers=headers)
    assert r.status_code == 200, f"status code should be 200 (actual: {r.status_code})"
    if isinstance(r.json(), list):
        return None
    output_dir = os.path.join(output_dir, r.json()['id'])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    output_path = os.path.join(output_dir, "manifest.json")
    with open(output_path, 'w') as f:
        json.dump(r.json(), f)
    return r.json()['id']


def upload_nc(filepath, manifestId):
    from urllib3 import encode_multipart_formdata

    (content, header) = encode_multipart_formdata({
      "tool-path": ("tool_path_example", open(filepath, "rb").read())
    })

    headers["Content-Type"] = header

    r = requests.put(f"{adminApiUrl}/fusion/{manifestId}", headers=headers, data=content)

    assert r.status_code == 200, f"status code should be 200 (actual: {r.status_code})"


def process_tool_path():
    pass


def find_fusion():
    fusions = glob.glob(FUSIONS_PRODUCTION_FOLDER + "/**/Fusion360.exe", recursive=True)
    assert len(fusions), "failed to find fusion"
    fusions.sort(key=lambda x: os.path.getmtime(x))
    return fusions[-1]  # most recent is last

import subprocess

def main():
    try:
        while True:
            fusion_job_path = None

            cloud = Cloud()
            nfc_count = cloud.count_jobs_from_manufacturing_to_awaiting_nfc()
            if nfc_count >= 400:
                print("Too many jobs in awaiting nfc, waiting")
                time.sleep(1)
                continue
            try:
                # shutil.rmtree(PROCESS_DIR_PATH)
                # os.mkdir(PROCESS_DIR_PATH)
                manifest_id = download_model(PROCESS_DIR_PATH)
                fusion_job_path = os.path.join(PROCESS_DIR_PATH, manifest_id)

                d = dict(os.environ)
                d["FUSION_JOB_PATH"] = fusion_job_path
                proc = subprocess.Popen([find_fusion(), '--nologo', '--script', os.path.abspath('./CreateToolPath/CreateToolPath.py')], env=d)
                proc.wait()
                toolpath_path = os.path.join(fusion_job_path, 'toolpath.nc')
                if os.path.exists(toolpath_path):
                    upload_nc(toolpath_path, manifest_id)
                else:
                    with open(os.path.join(fusion_job_path, 'error.txt')) as f:
                        print(f.read(), file=sys.stderr)
                        exit(1)
            except BaseException as e:
                print(e, file=sys.stderr)
                time.sleep(1)
                continue
            finally:
                if fusion_job_path is not None and os.path.exists(fusion_job_path):
                    shutil.rmtree(fusion_job_path)
    except BaseException as e:
        print(e, file=sys.stderr)
        exit(1)


if __name__ == "__main__":
    main()
