// Copyright (C) 2013 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.its.rtc;

import java.io.IOException;
import java.net.URL;

import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Injector;

import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
import com.googlesource.gerrit.plugins.its.rtc.network.RTCClient;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcComment;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcRelatedLink;
import com.googlesource.gerrit.plugins.its.rtc.workitems.RtcWorkItem;

public class RTCItsFacade implements ItsFacade {

  public static final String GERRIT_CONFIG_RTC_USERNAME = "username";
  public static final String GERRIT_CONFIG_RTC_PASSWORD = "password";
  public static final String GERRIT_CONFIG_CCM_URL = "url";
  public static final String GERRIT_CONFIG_SSL_VERIFY = "sslVerify";

  private Logger log = LoggerFactory.getLogger(RTCItsFacade.class);

  private final String pluginName;
  Config gerritConfig;

  private RTCClient client;

  private Injector injector;

  @Inject
  public RTCItsFacade(@PluginName String pluginName,
      @GerritServerConfig Config gerritConfig, Injector injector) {
    this.pluginName = pluginName;
    try {
      this.injector = injector;
      this.gerritConfig = gerritConfig;
      client().ping();
      log.debug("Connected to RTC at " + getRtcUrl() + " as admin user "
          + getRtcUser());
    } catch (Exception ex) {
      log.warn("RTC is currently not available", ex);
    }
  }

  @Override
  public void addComment(String itemId, String comment) throws IOException {
    long workItem = Long.parseLong(itemId);
    log.debug("Adding comment " + comment + " to workItem " + workItem);
    RtcComment rtcComment =
        client().workItemsApi().addComment(workItem, comment);
    log.debug("Comment created: " + rtcComment);
  }

  @Override
  public void addRelatedLink(String itemId, URL relatedUrl, String description)
      throws IOException {
    long workItem = Long.parseLong(itemId);
    log.debug("Adding related link " + relatedUrl + " to workItem " + workItem
        + " with description " + description);
    RtcRelatedLink relatedLink =
        client().workItemsApi().addRelated(workItem, relatedUrl, description);
    log.debug("Related link " + relatedLink + " to workItem#" + workItem
        + " CREATED");
  }

  @Override
  public void performAction(String itemId, String actionName)
      throws IOException {
    long workItem = Long.parseLong(itemId);
    log.debug("Executing action " + actionName + " on workItem " + workItem);
    RtcWorkItem wip = client().workItemsApi().getWorkItem(workItem);
    log.debug(" - loaded workitem " + wip);
    wip = client().workItemsApi().performAction(wip, actionName);
    log.debug("New item state: : " + wip);
  }

  @Override
  public String healthCheck(Check check) throws IOException {
    client.ping();
    return "{\"status\"=\"ok\",\"system\"=\"RTC\",}";
  }

  private RTCClient client() {

    if (client == null) {
      client = injector.getInstance(RTCClient.class);
      client.setLoginCredentials(getRtcUser(), getRtcPassword());

      log.debug("RTC Client pointing to " + getRtcUrl() + " as " + getRtcUser());
    }

    return client;
  }

  private String getRtcPassword() {
    return gerritConfig.getString(pluginName, null,
        GERRIT_CONFIG_RTC_PASSWORD);
  }

  private String getRtcUser() {
    return gerritConfig.getString(pluginName, null,
        GERRIT_CONFIG_RTC_USERNAME);
  }

  private String getRtcUrl() {
    return gerritConfig.getString(pluginName, null, GERRIT_CONFIG_CCM_URL);
  }

  @Override
  public String createLinkForWebui(String url, String text) {
    return "<a href=\"" + url + "\">" + text + "</a>";
  }

  @Override
  public boolean exists(String itemId) throws IOException {
    long workItem = Long.parseLong(itemId);
    RtcWorkItem item = client().workItemsApi().getWorkItem(workItem);
    return item != null;
  }

}
