#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
import typer
import requests
import os
import zipfile
from subprocess import check_output
from subprocess import STDOUT
from subprocess import call
from subprocess import Popen
from pathlib import Path
from sys import platform
import shutil
import socket
import time

def download_and_unarchive(url, download_path, extract_dir = os.path.join(os.path.expanduser('~'), ".mft/")):

  response = requests.get(url, stream=True)
  file_size = int(response.headers['Content-Length'])
  with typer.progressbar(length=file_size) as progress:
    with open(download_path, "wb") as handle:
      for data in response.iter_content(chunk_size=8192 * 2):
        progress.update(len(data))
        handle.write(data)

  print("Un archiving ....")
  with zipfile.ZipFile(download_path,"r") as zip_ref:
    zip_ref.extractall(extract_dir)

  os.remove(download_path)

def restart_service(bin_path, daemon_script_name):
  current_dir =  os.getcwd()
  try:
    os.chdir(bin_path)
    os.chmod(daemon_script_name, 0o744)
    rc = call(["./" + daemon_script_name, "stop"])
    rc = call(["./" + daemon_script_name, "start"])
  finally:
    os.chdir(current_dir)

def stop_service(bin_path, daemon_script_name):
  current_dir =  os.getcwd()
  try:
    os.chdir(bin_path)
    os.chmod(daemon_script_name, 0o744)
    rc = call(["./" + daemon_script_name, "stop"])
  finally:
    os.chdir(current_dir)


def validate_java_availability(required_version):
  """
      Issue 96: https://github.com/apache/airavata-mft/issues/96

      References:
      ---------
      https://stackoverflow.com/questions/31807882/get-java-version-number-from-python
      https://stackoverflow.com/questions/1332598/how-to-determine-whether-java-is-installed-on-a-system-through-python
      https://stackoverflow.com/questions/74206258/how-are-oracle-jdk-versions-numbered
      https://docs.python.org/3.8/library/subprocess.html#subprocess.check_output
      https://stackoverflow.com/questions/2411288/java-versioning-and-terminology-1-6-vs-6-0-openjdk-vs-sun
  """
  if shutil.which("java"):
    res = check_output(['java', '-version'], stderr=STDOUT).decode('utf-8')
    """
      res will have the value similar to the following
      openjdk version "17.0.5" 2022-10-18 LTS
      OpenJDK Runtime Environment Corretto-17.0.5.8.1 (build 17.0.5+8-LTS)
      OpenJDK 64-Bit Server VM Corretto-17.0.5.8.1 (build 17.0.5+8-LTS, mixed mode, sharing)
    """
    java_version = ''
    count = 0
    for c in res:
      if c == '"' or count == 1:
        if (c == '.' or c == '"') and count == 1:
          break
        if count == 0:
          count += 1
          continue
        java_version += c

    java_version = int(java_version)
    if java_version < required_version:
      print("Airavata MFT requires Java version " + required_version + " or higher")
      print("If you have more than one version of java please set java version "+ required_version +" or higher to the path")
      raise typer.Exit()
  else:
    print("Java is either not installed or path hasn't been set properly")
    raise typer.Exit()

def is_port_open(port):
  with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    return s.connect_ex(('localhost', port)) == 0

def start_mft():
  print("Setting up MFT Services")

  required_java_version = 11
  if platform == "linux" or platform == "linux2":
    consul_url = "https://releases.hashicorp.com/consul/1.7.1/consul_1.7.1_linux_amd64.zip"
    validate_java_availability(required_java_version)
  elif platform == "darwin":
    consul_url = "https://releases.hashicorp.com/consul/1.7.1/consul_1.7.1_darwin_amd64.zip"
    validate_java_availability(required_java_version)
  elif platform == "win32":
    print("Windows support is not available yet")
    raise typer.Exit()
  else:
    print("Un supported platform: " + platform)
    raise typer.Exit()

  mft_dir = os.path.join(os.path.expanduser('~'), ".mft")
  if not os.path.exists(mft_dir):
    os.makedirs(mft_dir)

  path = os.path.join(os.path.expanduser('~'), ".mft/consul")
  if not os.path.exists(path):
    print("Downloading Consul...")
    zip_path = os.path.join(os.path.expanduser('~'), ".mft/consul.zip")
    download_and_unarchive(consul_url, zip_path, os.path.join(os.path.expanduser('~'), ".mft/"))

  current_dir =  os.getcwd()
  try:
    os.chdir(os.path.join(os.path.expanduser('~'), ".mft"))
    os.chmod("consul", 0o744)

    if os.path.exists("consul.pid"):
      pid = Path('consul.pid').read_text()
      call(["kill", "-9", pid])

    consul_process = Popen(['nohup', './consul', "agent", "-dev"],
                     stdout=open('consul.log', 'w'),
                     stderr=open('consul.err.log', 'a'),
                     preexec_fn=os.setpgrp)

    print("Consul process id: " + str(consul_process.pid))
    with open("consul.pid", "w") as consul_pid:
      consul_pid.write(str(consul_process.pid))
  finally:
    os.chdir(current_dir)

  path = os.path.join(os.path.expanduser('~'), ".mft/Standalone-Service-0.01")
  if not os.path.exists(path):
    url = "https://github.com/apache/airavata-mft/releases/download/v0.0.1/Standalone-Service-0.01-bin.zip"
    print("Downloading MFT Server...")
    zip_path = os.path.join(os.path.expanduser('~'), ".mft/Standalone-Service-0.01-bin.zip")
    download_and_unarchive(url, zip_path)

  while not is_port_open(8500):
    print("Waiting for Consul to start...")
    time.sleep(1)

  restart_service(path + "/bin", "standalone-service-daemon.sh")

  print("MFT Started")


def stop_mft():
  print("Stopping MFT Services")

  path = os.path.join(os.path.expanduser('~'), ".mft/consul")
  if os.path.exists(path):
    current_dir =  os.getcwd()
    try:
      os.chdir(os.path.join(os.path.expanduser('~'), ".mft"))
      os.chmod("consul", 0o744)

      if os.path.exists("consul.pid"):
        pid = Path('consul.pid').read_text()
        call(["kill", "-9", pid])
    finally:
      os.chdir(current_dir)

  path = os.path.join(os.path.expanduser('~'), ".mft/Standalone-Service-0.01")
  if os.path.exists(path):
    stop_service(path + "/bin", "standalone-service-daemon.sh")

  print("MFT Stopped....")

def update_mft():
  stop_mft()

  mft_dir = os.path.join(os.path.expanduser('~'), ".mft")
  if os.path.exists(mft_dir):
    print("Removing .mft directory")
    shutil.rmtree(mft_dir)

  database = os.path.join(os.path.expanduser('~'), "mft_db.mv.db")
  if os.path.exists(database):
    os.remove(database)
  start_mft()

def print_log():
  log_file_path = os.path.join(os.path.expanduser('~'), ".mft", "Standalone-Service-0.01", "logs", "airavata.log")
  log_file = open(log_file_path,"r")
  lines = follow_file(log_file)
  for line in lines:
    print(line)

def follow_file(file):
  #file.seek(0, os.SEEK_END)

  while True:
    line = file.readline()
    if not line:
      time.sleep(0.1)
      continue

    yield line


