/*
 * 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.support

import com.google.gerrit.extensions.restapi.TopLevelResource
import com.google.gerrit.server.account.CapabilityControl
import com.google.gerrit.server.plugins.{ListPlugins, PluginsCollection}
import com.google.gson.JsonElement
import com.google.inject.{ImplementedBy, Inject}
import com.googlesource.gerrit.plugins.support.legacy.LegacyCapabilityControl

import scala.util.{Failure, Success, Try}

object GerritFacade {

  class PluginName(val value: String) extends AnyRef

  implicit class PimpedCapabilityControl(val cc: CapabilityControl) extends AnyVal {

    def canDo(operation: String)(implicit pluginName: PluginName) = LegacyCapabilityControl(cc).canPerform(operation)
  }
}

object TryAll {
  def apply[T](block: => T): Try[T] = {
    try {
      val res:T = block
      Success(res)
    } catch {
      case t: Throwable => Failure(t)
    }
  }
}

// Structure of the JSON fields returned by the pluginsInfo method
case class PluginInfo(id: String, version: String, indexUrl: String, disabled: Boolean)

@ImplementedBy(classOf[GerritPluginsInfoProvider])
trait PluginsInfoProvider {

  def getPluginsInfo: JsonElement
}

class GerritPluginsInfoProvider @Inject() (val pluginsCollection: PluginsCollection) extends PluginsInfoProvider {

  override def getPluginsInfo: JsonElement = {
    pluginsCollection
      .list
      .asInstanceOf[ListPlugins]
      .apply(TopLevelResource.INSTANCE).asInstanceOf[JsonElement]
  }
}
