// Copyright (C) 2017 The Android Open Source Project
//
// Licensed 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.
package com.googlesource.gerrit.plugins.analytics.wizard
import java.net.URLEncoder
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.Path

import com.google.common.io.ByteStreams
import com.google.gerrit.extensions.annotations.PluginData
import com.google.gerrit.extensions.restapi.{
  Response,
  RestApiException,
  RestModifyView,
  RestReadView
}
import com.google.gerrit.server.config.GerritServerConfig
import com.google.gerrit.server.project.ProjectResource
import com.google.inject.{ImplementedBy, Inject}
import com.googlesource.gerrit.plugins.analytics.wizard.AnalyticDashboardSetup.writer
import com.googlesource.gerrit.plugins.analytics.wizard.model.{
  ETLConfig,
  ETLConfigRaw,
  ETLConfigValidationError
}
import com.googlesource.gerrit.plugins.analytics.wizard.utils._
import com.spotify.docker.client.messages.ContainerInfo
import com.spotify.docker.client.{DefaultDockerClient, DockerClient}
import org.eclipse.jgit.lib.Config

import scala.util.{Failure, Success}
case class Input(dashboardName: String, etlConfig: ETLConfigRaw)
class PutAnalyticsStack @Inject()(@PluginData val dataPath: Path,
                                  @GerritServerConfig gerritConfig: Config)
    extends RestModifyView[ProjectResource, Input] {
  override def apply(resource: ProjectResource, input: Input): Response[String] = {
    val projectName                                             = resource.getName
    val encodedName                                             = AnalyticsWizardActions.encodedName(projectName)
    val etlConfigE: Either[ETLConfigValidationError, ETLConfig] = ETLConfig.fromRaw(input.etlConfig)
    etlConfigE.fold(
      configError =>
        Response.withStatusCode(400,
                                s"Cannot create dashboard configuration: ${configError.message}"),
      etlConfig => {
        val configHelper = new GerritConfigHelper(gerritConfig) with LocalAddressGetter
        configHelper.getGerritLocalAddress match {
          case Success(gerritLocalUrl) =>
            AnalyticDashboardSetup(
              input.dashboardName,
              dataPath.resolve(s"docker-compose.${input.dashboardName}.yaml"),
              gerritLocalUrl,
              etlConfig
            ).createDashboardSetupFile()
            Response.created(s"Dashboard configuration created for $encodedName!")
          case Failure(exception) =>
            Response.withStatusCode(
              500,
              s"Cannot create dashboard configuration - '${exception.getMessage}'")
        }
      }
    )
  }
}
class DockerComposeCommand(var action: String, var dashboardName: String)
class PostAnalyticsStack @Inject()(@PluginData val dataPath: Path)
    extends RestModifyView[ProjectResource, DockerComposeCommand] {
  override def apply(resource: ProjectResource, input: DockerComposeCommand): Response[String] = {
    val encodedName = AnalyticsWizardActions
      .encodedName(input.dashboardName)
    val pb = new ProcessBuilder(
      "docker-compose",
      "-f",
      s"${dataPath.toFile.getAbsolutePath}/docker-compose.${encodedName}.yaml",
      input.action.toLowerCase,
      "--detach"
    )
    pb.redirectErrorStream(true)
    val ps: Process = pb.start
    ps.getOutputStream.close
    val output =
      new String(ByteStreams.toByteArray(ps.getInputStream), UTF_8)
    ps.waitFor
    ps.exitValue match {
      case 0 => Response.created(output)
      case _ =>
        throw new RestApiException(s"Failed with exit code: ${ps.exitValue} - $output")
    }
  }
}
class GetAnalyticsStackStatus @Inject()(@PluginData val dataPath: Path,
                                        val dockerClientProvider: DockerClientProvider)
    extends RestReadView[ProjectResource] {
  override def apply(resource: ProjectResource): Response[String] = {
    val containerName = "analytics-wizard_spark-gerrit-analytics-etl_1"
    responseFromContainerInfo(dockerClientProvider.client.inspectContainer(containerName))
  }
  private def responseFromContainerInfo(containerInfo: ContainerInfo) = {
    containerInfo.state match {
      case s if s.exitCode != 0 =>
        throw new RestApiException(s"Data import failed")
      case s if s.running =>
        Response.withStatusCode(202, "processing")
      case s if s.status == "exited" =>
        //Spark ETL job exited successfully
        Response.withStatusCode(204, "finished")
      case _ => throw new RestApiException(s"Case not handled")
    }
  }
}
object AnalyticsWizardActions {
  // URLEncoder could potentially throw UnsupportedEncodingException,
  // but UTF-8 will *always* be resolved, otherwise, Gerrit wouldn't work at all
  def encodedName(name: String) =
    try {
      URLEncoder.encode(name, "UTF-8")
    } catch {
      case e: Throwable => throw new RuntimeException(e)
    }
}
@ImplementedBy(classOf[DockerClientProviderImpl])
trait DockerClientProvider {
  def client: DockerClient
}
class DockerClientProviderImpl extends DockerClientProvider {
  def client: DockerClient = DefaultDockerClient.fromEnv.build
}
