# This file is part of OpenModelica.
#
# Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
# c/o Linköpings universitet, Department of Computer and Information Science,
# SE-58183 Linköping, Sweden.
#
# All rights reserved.
#
# THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
# THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
# ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
# RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
# VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
#
# The OpenModelica software and the OSMC (Open Source Modelica Consortium)
# Public License (OSMC-PL) are obtained from OSMC, either from the above
# address, from the URLs:
# http://www.openmodelica.org or
# https://github.com/OpenModelica/ or
# http://www.ida.liu.se/projects/OpenModelica,
# and in the OpenModelica distribution.
#
# GNU AGPL version 3 is obtained from:
# https://www.gnu.org/licenses/licenses.html#GPL
#
# This program is distributed WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
# IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
#
# See the full OSMC Public License conditions for more details.

import os
import platform
import shutil
import sys
import sysconfig
import tempfile
from setuptools.command.build_py import build_py

# check for requests package
try:
  import requests
except ImportError:
  import subprocess
  subprocess.check_call([sys.executable, "-m", "pip", "install", "requests"])
  import requests

class OMSInstaller(build_py):
  """
  Custom build_py command to download OMSimulator binaries and copy them
  into the package during build.
  """
  def __init__(self, dist):
    # check if directory exist and remove
    topdir = os.path.join(os.getcwd(), 'OMSimulator')
    if os.path.isdir(topdir):
      shutil.rmtree(topdir)

    # recreate it, so that setuptools creates the package directory
    os.mkdir(topdir)
     # initialize parent
    super().__init__(dist)

  def fetch_oms(self):
    target_dir = os.path.join(self.build_lib, "OMSimulator")
    os.makedirs(target_dir, exist_ok=True)

    # Select platform-specific download
    if (sysconfig.get_platform() == 'linux-x86_64'):
      info = platform.freedesktop_os_release()
      version = info.get("VERSION_ID", "")
      if version.startswith("24.04"):
        url = 'https://build.openmodelica.org/omsimulator/nightly/linux-amd64/OMSimulator-linux-amd64-@OMS_VERSION_STRING@.tar.gz'
      else:
        url = 'https://build.openmodelica.org/omsimulator/nightly/linux-focal-amd64/OMSimulator-linux-focal-amd64-@OMS_VERSION_STRING@.tar.gz'
      dll_path  = "lib/x86_64-linux-gnu/libOMSimulator.so"
      source_path = "lib/x86_64-linux-gnu/OMSimulator"
    elif (sysconfig.get_platform() == "mingw_x86_64_ucrt" or (sysconfig.get_platform() == 'mingw' and platform.architecture()[0] == '64bit')):
      url = 'https://build.openmodelica.org/omsimulator/nightly/win-mingw-ucrt64/OMSimulator-mingw-ucrt64-@OMS_VERSION_STRING@.zip'
      dll_path  = "bin/libOMSimulator.dll"
      source_path = "lib/OMSimulator"
    elif (sysconfig.get_platform() == 'win-amd64'):
      url = 'https://build.openmodelica.org/omsimulator/nightly/win-msvc64/OMSimulator-win64-@OMS_VERSION_STRING@.zip'
      dll_path  = "bin/OMSimulator.dll"
      source_path = "lib/OMSimulator"
    elif (platform.system() == 'Darwin'):
      url = 'https://build.openmodelica.org/omsimulator/nightly/osx/OMSimulator-osx-@OMS_VERSION_STRING@.zip'
      dll_path  = "lib/libOMSimulator.dylib"
      ## the path needs to be checked, as of now we are not buiding artifacts for macos
      source_path = "lib/OMSimulator"
    else:
      raise Exception("Platform not supported for {} ".format(sysconfig.get_platform()))

    response = requests.get(url, verify=False)
    if response.status_code != 200:
      raise Exception(f"Failed to download {url}")

    # Save temp file
    temp_dir = tempfile.mkdtemp(dir=os.getcwd())
    zip_file = os.path.join(temp_dir, os.path.basename(url))
    with open(zip_file, "wb") as f:
      f.write(response.content)

    # Extract archive
    extract_dir = os.path.join(temp_dir, "OMSimulator_extract")
    if os.path.exists(extract_dir):
      shutil.rmtree(extract_dir)

    shutil.unpack_archive(zip_file, extract_dir)

    # Copy package
    shutil.copytree(os.path.join(extract_dir, source_path), target_dir, dirs_exist_ok=True)
    # Copy schema if exists
    schema_src = os.path.join(extract_dir, "share/OMSimulator/schema")
    if os.path.exists(schema_src):
      shutil.copytree(schema_src, os.path.join(target_dir, "schema"), dirs_exist_ok=True)
    # Copy DLL
    dll_src = os.path.join(extract_dir, dll_path)
    if os.path.exists(dll_src):
      shutil.copy2(dll_src, target_dir)

    # Cleanup
    shutil.rmtree(temp_dir)

  def run(self):
    if not self.dry_run:
      self.fetch_oms()
    super().run()


# --------------------------
# Standalone testing
# --------------------------
if __name__ == "__main__":
  from setuptools import Distribution
  dist = Distribution()
  installer = OMSInstaller(dist)
  installer.build_lib = os.getcwd()
  installer.fetch_oms()