﻿// 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.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using Org.Apache.REEF.Client.API.Exceptions;
using Org.Apache.REEF.Tang.Annotations;
using Org.Apache.REEF.Utilities.Diagnostics;
using Org.Apache.REEF.Utilities.Logging;

namespace Org.Apache.REEF.Client.Common
{
    /// <summary>
    /// Helper class to launch the java side of the various clients.
    /// </summary>
    internal class JavaClientLauncher : IJavaClientLauncher
    {
        /// <summary>
        /// The folder in which we search for the client jar.
        /// </summary>
        private const string JarFolder = "./";

        private static readonly Logger Logger = Logger.GetLogger(typeof(JavaClientLauncher));
        private readonly IList<string> _additionalClasspathEntries = new List<string>();

        [Inject]
        private JavaClientLauncher()
        {
        }

        /// <summary>
        /// Launch a java class in ClientConstants.ClientJarFilePrefix with provided parameters.
        /// </summary>
        /// <param name="javaClassName"></param>
        /// <param name="parameters"></param>
        public void Launch(string javaClassName, params string[] parameters)
        {
            var startInfo = new ProcessStartInfo
            {
                Arguments = AssembleArguments(javaClassName, parameters),
                FileName = GetJavaCommand(),
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };

            var msg = string.Format(CultureInfo.CurrentCulture, "Launch Java with command: {0} {1}",
                startInfo.FileName, startInfo.Arguments);
            Logger.Log(Level.Info, msg);

            var process = Process.Start(startInfo);
            if (process != null)
            {
                process.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
                {
                    if (!string.IsNullOrWhiteSpace(e.Data))
                    {
                        Logger.Log(Level.Info, e.Data);
                    }
                };
                process.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e)
                {
                    if (!string.IsNullOrWhiteSpace(e.Data))
                    {
                        Logger.Log(Level.Error, e.Data);
                    }
                };
                process.BeginErrorReadLine();
                process.BeginOutputReadLine();
                process.WaitForExit();
            }
            else
            {
                Exceptions.Throw(new Exception("Java client process didn't start."), Logger);
            }
        }

        /// <summary>
        /// Assembles the command line arguments. Used by Launch()
        /// </summary>
        /// <param name="javaClassName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private string AssembleArguments(string javaClassName, params string[] parameters)
        {
            IList<string> arguments = new List<string>();
            arguments.Add("-cp");
            arguments.Add(GetClientClasspath());
            arguments.Add(javaClassName);
            foreach (var parameter in parameters)
            {
                arguments.Add(parameter);
            }
            return string.Join(" ", arguments);
        }

        /// <summary>
        /// Find the `java` command on this machine and returns its path.
        /// </summary>
        /// <exception cref="JavaNotFoundException">If the java binary couldn't be found.</exception>
        /// <returns>The path of the `java` command on this machine.</returns>
        private static string GetJavaCommand()
        {
            var javaHomePath = Environment.GetEnvironmentVariable("JAVA_HOME");
            if (string.IsNullOrWhiteSpace(javaHomePath))
            {
                // TODO: Attempt to find java via the registry.
                Exceptions.Throw(
                    new JavaNotFoundException("JAVA_HOME isn't set. Please install Java and make set JAVA_HOME"), Logger);
            }

            if (!Directory.Exists(javaHomePath))
            {
                Exceptions.Throw(
                    new JavaNotFoundException("JAVA_HOME references a folder that doesn't exist.", javaHomePath), Logger);
            }

            var javaBinPath = Path.Combine(javaHomePath, "bin");
            if (!Directory.Exists(javaBinPath))
            {
                throw new JavaNotFoundException(
                    "JAVA_HOME references a folder that doesn't contain a `bin` folder. Please adjust JAVA_HOME",
                    javaHomePath);
            }

            var javaPath = Path.Combine(javaBinPath, "java.exe");
            if (!File.Exists(javaPath))
            {
                Exceptions.Throw(
                    new JavaNotFoundException(
                        "Could not find java.exe on this machine. Is Java installed and JAVA_HOME set?", javaPath),
                    Logger);
            }
            return javaPath;
        }

        /// <summary>
        /// Assembles the classpath for the side process
        /// </summary>
        /// <exception cref="ClasspathException">If the classpath would be empty.</exception>
        /// <returns></returns>
        private string GetClientClasspath()
        {
            var files = Directory.GetFiles(JarFolder)
                .Where(x => (!string.IsNullOrWhiteSpace(x)))
                .Where(e => Path.GetFileName(e).ToLower().StartsWith(ClientConstants.ClientJarFilePrefix))
                .ToList();

            if (files.Count == 0)
            {
                Exceptions.Throw(new ClasspathException(
                    "Unable to assemble classpath. Make sure the REEF JAR is in the current working directory."), Logger);
            }

            var classpathEntries = new List<string>(_additionalClasspathEntries).Concat(files);
            return string.Join(";", classpathEntries);
        }

        /// <summary>
        /// Add entries to the end of the classpath of the java client.
        /// </summary>
        /// <param name="entries"></param>
        public void AddToClassPath(IEnumerable<string> entries)
        {
            foreach (var entry in entries)
            {
                _additionalClasspathEntries.Add(entry);
            }
        }
    }
}