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

package org.apache.s2graph.graphql.types

import org.apache.s2graph.core.schema._
import org.apache.s2graph.graphql.repository.GraphRepository
import sangria.schema._

import scala.language.existentials
import scala.util.{Failure, Success, Try}
import org.apache.s2graph.graphql.types.S2Type.{ServiceColumnParam}

object ManagementType {

  import sangria.schema._

  case class MutationResponse[T](result: Try[T])

  def makeMutationResponseType[T](name: String, desc: String, tpe: ObjectType[_, T]): ObjectType[Unit, MutationResponse[T]] = {
    val retType = ObjectType(
      name,
      desc,
      () => fields[Unit, MutationResponse[T]](
        Field("isSuccess",
          BooleanType,
          resolve = _.value.result.isSuccess
        ),
        Field("message",
          StringType,
          resolve = _.value.result match {
            case Success(_) => s"Mutation successful"
            case Failure(ex) => ex.getMessage
          }
        ),
        Field("object",
          OptionType(tpe),
          resolve = _.value.result.toOption
        )
      )
    )

    retType
  }
}

class ManagementType(repo: GraphRepository) {

  import ManagementType._
  import sangria.macros.derive._
  import org.apache.s2graph.graphql.bind.Unmarshaller._
  import org.apache.s2graph.graphql.types.StaticTypes._

  val services = repo.services()
  val serviceColumns = repo.serviceColumns()
  val labels = repo.labels()

  lazy val serviceColumnOnServiceWithPropInputObjectFields = services.map { service =>
    InputField(service.serviceName.toValidName, OptionInputType(InputObjectType(
      s"Input_${service.serviceName.toValidName}_ServiceColumn_Props",
      description = "desc here",
      fields = List(
        InputField("columnName", makeServiceColumnEnumTypeOnService(service)),
        InputField("props", ListInputType(InputPropType))
      )
    )))
  }

  lazy val serviceColumnOnServiceInputObjectFields = services.map { service =>
    InputField(service.serviceName.toValidName, OptionInputType(InputObjectType(
      s"Input_${service.serviceName.toValidName}_ServiceColumn",
      description = "desc here",
      fields = List(
        InputField("columnName", makeServiceColumnEnumTypeOnService(service))
      )
    )))
  }

  def makeServiceColumnEnumTypeOnService(service: Service): EnumType[String] = {
    val columns = service.serviceColumns(false).toList
    EnumType(
      s"Enum_${service.serviceName.toValidName}_ServiceColumn",
      description = Option("desc here"),
      values =
        if (columns.isEmpty) dummyEnum :: Nil
        else columns.map { column =>
          EnumValue(column.columnName.toValidName, value = column.columnName)
        }
    )
  }

  lazy val labelPropsInputFields = labels.map { label =>
    InputField(label.label.toValidName, OptionInputType(InputObjectType(
      s"Input_${label.label.toValidName}_props",
      description = "desc here",
      fields = List(
        InputField("props", ListInputType(InputPropType))
      )
    )))
  }

  lazy val ServiceType = deriveObjectType[GraphRepository, Service](
    ObjectTypeName("Service"),
    ObjectTypeDescription("desc here"),
    RenameField("serviceName", "name"),
    AddFields(
      Field("serviceColumns", ListType(ServiceColumnType), resolve = c => c.value.serviceColumns(false).toList)
    )
  )

  lazy val ServiceColumnType = deriveObjectType[GraphRepository, ServiceColumn](
    ObjectTypeName("ServiceColumn"),
    ObjectTypeDescription("desc here"),
    RenameField("columnName", "name"),
    AddFields(
      Field("props", ListType(ColumnMetaType),
        resolve = c => c.value.metasWithoutCache.filter(ColumnMeta.isValid)
      )
    )
  )

  val dummyEnum = EnumValue("_", value = "_")

  lazy val ServiceListType = EnumType(
    s"Enum_Service",
    description = Option("desc here"),
    values = {
      if (services.isEmpty) dummyEnum :: Nil
      else services.map { service =>
        EnumValue(service.serviceName.toValidName, value = service.serviceName)
      }
    }
  )

  lazy val ServiceColumnListType = EnumType(
    s"Enum_ServiceColumn",
    description = Option("desc here"),
    values = {
      if (serviceColumns.isEmpty) dummyEnum :: Nil
      else serviceColumns.map { serviceColumn =>
        EnumValue(serviceColumn.columnName.toValidName, value = serviceColumn.columnName)
      }
    }
  )

  lazy val EnumLabelsType = EnumType(
    s"Enum_Label",
    description = Option("desc here"),
    values = {
      if (labels.isEmpty) dummyEnum :: Nil
      else labels.map { label =>
        EnumValue(label.label.toValidName, value = label.label)
      }
    }
  )

  lazy val ServiceMutationResponseType = makeMutationResponseType[Service](
    "MutateService",
    "desc here",
    ServiceType
  )

  lazy val ServiceColumnMutationResponseType = makeMutationResponseType[ServiceColumn](
    "MutateServiceColumn",
    "desc here",
    ServiceColumnType
  )

  lazy val LabelMutationResponseType = makeMutationResponseType[Label](
    "MutateLabel",
    "desc here",
    LabelType
  )

  lazy val labelsField: Field[GraphRepository, Any] = Field(
    "Labels",
    ListType(LabelType),
    description = Option("desc here"),
    arguments = List(LabelNameArg),
    resolve = { c =>
      c.argOpt[String]("name") match {
        case Some(name) => c.ctx.labels().filter(_.label == name)
        case None => c.ctx.labels()
      }
    }
  )

  val serviceOptArgs = List(
    "compressionAlgorithm" -> CompressionAlgorithmType,
    "cluster" -> StringType,
    "hTableName" -> StringType,
    "preSplitSize" -> IntType,
    "hTableTTL" -> IntType
  ).map { case (name, _type) => Argument(name, OptionInputType(_type)) }

  val AddPropServiceType = InputObjectType[ServiceColumnParam](
    "Input_Service_ServiceColumn_Props",
    description = "desc",
    fields =
      if (serviceColumnOnServiceWithPropInputObjectFields.isEmpty) DummyInputField :: Nil
      else serviceColumnOnServiceWithPropInputObjectFields
  )

  val ServiceColumnSelectType = InputObjectType[ServiceColumnParam](
    "Input_Service_ServiceColumn",
    description = "desc",
    fields =
      if (serviceColumnOnServiceInputObjectFields.isEmpty) DummyInputField :: Nil
      else serviceColumnOnServiceInputObjectFields
  )

  val InputServiceType = InputObjectType[ServiceColumnParam](
    "Input_Service",
    description = "desc",
    fields =
      if (serviceColumnOnServiceInputObjectFields.isEmpty) DummyInputField :: Nil
      else serviceColumnOnServiceInputObjectFields
  )

  lazy val servicesField: Field[GraphRepository, Any] = Field(
    "Services",
    ListType(ServiceType),
    description = Option("desc here"),
    arguments = List(ServiceNameArg),
    resolve = { c =>
      c.argOpt[String]("name") match {
        case Some(name) => c.ctx.services().filter(_.serviceName.toValidName == name)
        case None => c.ctx.services()
      }
    }
  )

  /**
    * Query Fields
    * Provide s2graph management query API
    */
  lazy val queryFields: List[Field[GraphRepository, Any]] = List(servicesField, labelsField)

  /**
    * Mutation fields
    * Provide s2graph management mutate API
    *
    * - createService
    * - createLabel
    * - ...
    */

  lazy val labelRequiredArg = List(
    Argument("sourceService", InputServiceType),
    Argument("targetService", InputServiceType)
  )

  val labelOptsArgs = List(
    Argument("serviceName", OptionInputType(ServiceListType)),
    Argument("consistencyLevel", OptionInputType(ConsistencyLevelType)),
    Argument("isDirected", OptionInputType(BooleanType)),
    Argument("isAsync", OptionInputType(BooleanType)),
    Argument("schemaVersion", OptionInputType(StringType))
  )

  val NameArg = Argument("name", StringType, description = "desc here")

  lazy val ServiceNameArg = Argument("name", OptionInputType(ServiceListType), description = "desc here")

  lazy val ServiceNameRawArg = Argument("serviceName", ServiceListType, description = "desc here")

  lazy val ColumnNameArg = Argument("columnName", OptionInputType(ServiceColumnListType), description = "desc here")

  lazy val ColumnTypeArg = Argument("columnType", DataTypeType, description = "desc here")

  lazy val LabelNameArg = Argument("name", OptionInputType(EnumLabelsType), description = "desc here")

  lazy val PropArg = Argument("props", OptionInputType(ListInputType(InputPropType)), description = "desc here")

  lazy val IndicesArg = Argument("indices", OptionInputType(ListInputType(InputIndexType)), description = "desc here")

  lazy val mutationFields: List[Field[GraphRepository, Any]] = List(
    Field("createService",
      ServiceMutationResponseType,
      arguments = NameArg :: serviceOptArgs,
      resolve = c => MutationResponse(c.ctx.createService(c.args))
    ),
    Field("createLabel",
      LabelMutationResponseType,
      arguments = NameArg :: PropArg :: IndicesArg :: labelRequiredArg ::: labelOptsArgs,
      resolve = c => MutationResponse(c.ctx.createLabel(c.args))
    ),
    Field("deleteLabel",
      LabelMutationResponseType,
      arguments = LabelNameArg :: Nil,
      resolve = c => MutationResponse(c.ctx.deleteLabel(c.args))
    ),
    Field("createServiceColumn",
      ServiceColumnMutationResponseType,
      arguments = List(ServiceNameRawArg, Argument("columnName", StringType), ColumnTypeArg, PropArg),
      resolve = c => MutationResponse(c.ctx.createServiceColumn(c.args))
    ),
    Field("deleteServiceColumn",
      ServiceColumnMutationResponseType,
      arguments = Argument("service", ServiceColumnSelectType) :: Nil,
      resolve = c => MutationResponse(c.ctx.deleteServiceColumn(c.args))
    ),
    Field("addPropsToServiceColumn",
      ServiceColumnMutationResponseType,
      arguments = Argument("service", AddPropServiceType) :: Nil,
      resolve = c => MutationResponse(c.ctx.addPropsToServiceColumn(c.args))
    ),
    Field("addPropsToLabel",
      LabelMutationResponseType,
      arguments = Argument("labelName", EnumLabelsType) :: PropArg :: Nil,
      resolve = c => MutationResponse(c.ctx.addPropsToLabel(c.args))
    )
  )
}
