Added configInfo capability.

When specifying configInfo=true plugin now fetches all the files with
.config suffix and include their content in the generated zip file.

Change-Id: I4c7487fe97a0ff49e64d06948ed3c8b86d888890
diff --git a/src/main/resources/Documentation/rest-api.md b/src/main/resources/Documentation/rest-api.md
index abad4b6..2f7d684 100644
--- a/src/main/resources/Documentation/rest-api.md
+++ b/src/main/resources/Documentation/rest-api.md
@@ -29,8 +29,8 @@
     "diskUsable": 95003811840,
     "path": "/home/pakkio/g2.14-stable/data"
 }
-
 ```
+- configInfo - This will add in the zip all the *.config files in the $GERRIT/etc folder
 
 NOTE: API must be authenticated with the credentials of a user with the
 'Collect Server Data' capability.
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportCommands.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportCommands.scala
index 0371a23..500a0a5 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportCommands.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/GerritSupportCommands.scala
@@ -16,6 +16,8 @@
 
 package com.googlesource.gerrit.plugins.support
 
+import java.nio.charset.Charset
+
 import com.google.gson.{Gson, JsonElement, JsonObject}
 import com.google.inject._
 import com.googlesource.gerrit.plugins.support.GerritSupportCommand.{CommandResult, JsonResult, ResultName}
@@ -34,23 +36,33 @@
   // allows returning a pure Json result or a textual file content
   case class CommandResult(entryName: ResultName, content: AnyResult)
 
-  trait AnyResult
+  trait AnyResult {
+    def getBytes: Array[Byte]
+  }
 
   case class JsonResult(result: JsonElement)(implicit val gson: Gson) extends AnyResult {
-    override def toString: String = gson.toJson(result)
+    override def getBytes: Array[Byte] = gson.toJson(result)
   }
 
   case class TextResult(result: String) extends AnyResult {
-    override def toString: String = result
+    override def getBytes: Array[Byte] = result
   }
 
-  implicit def convertAny2CommandResult(x: Any)(implicit resultName: ResultName, gson: Gson) =
+  case class BinResult(result: Array[Byte]) extends AnyResult {
+    override def getBytes: Array[Byte] = result
+  }
+
+  implicit def convertAny2CommandResult(x: Any)(implicit resultName: ResultName, gson: Gson): CommandResult =
     x match {
       case res: AnyResult => CommandResult(resultName, res)
       case anyRes => CommandResult(resultName, JsonResult(gson.toJsonTree(anyRes)))
     }
 
-  implicit def convertString2TextResult(x:String) = TextResult(x)
+  val UTF8 = Charset.forName("UTF-8")
+
+  implicit def convertStringToBinary(x:String):Array[Byte] = x.getBytes(UTF8)
+  implicit def convertString2TextResult(x:String): TextResult = TextResult(x)
+  implicit def convertBinary2BinResult(x:Array[Byte]): BinResult = BinResult(x)
 }
 
 abstract class GerritSupportCommand {
@@ -66,7 +78,7 @@
 
   def getResults: Seq[CommandResult] = Seq(getResult)
 
-  def getResult: CommandResult
+  def getResult: CommandResult = null
 
   def execute: Seq[CommandResult] = {
     Try {
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala
index d72c0d6..f145eb2 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/SupportBundle.scala
@@ -65,7 +65,7 @@
     val zipBundle =  new ZipOutputStream(new FileOutputStream(file))
     results.foreach { result =>
       zipBundle.putNextEntry(new ZipEntry(result.entryName))
-      zipBundle.write(result.content.toString.getBytes(UTF8))
+      zipBundle.write(result.content.getBytes)
     }
     zipBundle.close()
     file
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/support/commands/ConfigInfoCommand.scala b/src/main/scala/com/googlesource/gerrit/plugins/support/commands/ConfigInfoCommand.scala
new file mode 100644
index 0000000..ae46468
--- /dev/null
+++ b/src/main/scala/com/googlesource/gerrit/plugins/support/commands/ConfigInfoCommand.scala
@@ -0,0 +1,50 @@
+/*
+ * 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.commands
+
+import java.io.File
+import java.nio.file.Files
+
+import com.google.inject.Inject
+import com.googlesource.gerrit.plugins.support.GerritSupportCommand.{BinResult, CommandResult}
+import com.googlesource.gerrit.plugins.support._
+
+import scala.util.{Failure, Success, Try}
+
+class ConfigInfoCommand @Inject()(val sitePathsWrapper: SitePathsWrapper)
+  extends GerritSupportCommand {
+
+  override def getResults = {
+    try {
+      sitePathsWrapper
+        .getAsPath("etc_dir")
+        .toFile
+        .listFiles
+        .filter(_.isFile)
+        .filter(_.getName.endsWith(".config"))
+        .map(f => CommandResult(
+          f.getName,
+          BinResult(Files.readAllBytes(f.toPath))))
+    } catch {
+      case e: Exception =>
+        val error =
+          s"Error while processing config file listing: ${e.getMessage}"
+        log.error(error)
+        Seq(CommandResult(name, error))
+    }
+  }
+}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala b/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala
index 3ef19f0..9384c37 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/support/GerritSupportTest.scala
@@ -18,7 +18,7 @@
 
 import java.nio.file.Paths
 
-import com.googlesource.gerrit.plugins.support.GerritSupportCommand.{CommandResult, JsonResult, ResultName, TextResult}
+import com.googlesource.gerrit.plugins.support.GerritSupportCommand._
 import com.googlesource.gerrit.plugins.support.commands._
 import org.mockito.Matchers.any
 import org.mockito.Mockito
@@ -61,5 +61,16 @@
     diskInfo.getAsJsonObject should haveValidFields
   }
 
+  "config-info command" should "return some binary content" in {
+    val wrapper = Mockito.mock(classOf[SitePathsWrapper])
+    Mockito.when(wrapper.getAsPath(any[String])).thenReturn(tmpPath.toPath)
+    tmpConfigFile
+    val commands = new ConfigInfoCommand(wrapper).execute
+    commands should not be empty
+    val BinResult(content) = commands.head.content
+
+    content should not be empty
+  }
+
 }