// Copyright (C) 2014 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.storyboard;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class StoryboardClient {

  private static final Logger log = LoggerFactory.getLogger(
      StoryboardClient.class);

  public static final String STORIES_ENDPOINT = "/api/v1/stories";
  public static final String SYS_INFO_ENDPOINT = "/api/v1/systeminfo";

  private final String baseUrl;
  private final String password;

  public StoryboardClient(final String baseUrl, String password) {
    this.baseUrl = baseUrl;
    this.password = password;
  }

  // generic method to get data from a REST endpoint
  public String getData(final String url) throws IOException {

    HttpGet httpget = new HttpGet(url);
    try (CloseableHttpClient client = HttpClients.createDefault();
      CloseableHttpResponse response = client.execute(httpget)) {
      log.debug("Making request for " + httpget.getRequestLine());
      StatusLine sl = response.getStatusLine();
      int responseCode = sl.getStatusCode();
      if (responseCode == HttpURLConnection.HTTP_OK) {
        log.debug("Retreiving data from response " + httpget.getRequestLine());
        InputStream inputStream = response.getEntity().getContent();
        Reader reader = new InputStreamReader(inputStream);
        int contentLength = (int) response.getEntity().getContentLength();
        char[] charArray = new char[contentLength];
        reader.read(charArray);
        String responseJson = new String(charArray);
        log.debug("Data retreived: " + responseJson);
        return responseJson;
      } else {
        log.error("Failed request: " + httpget.getRequestLine() +
            " with response: " + responseCode);
      }
    }
    return null;
  }

  // generic method to POST data with a REST endpoint
  public void postData(final String url, final String data)
      throws IOException {

    HttpPost httpPost = new HttpPost(url);
    httpPost.addHeader("Authorization", "Bearer " + password);
    httpPost.addHeader("Content-Type", "application/json; charset=utf-8");
    httpPost.setEntity(new StringEntity(data, "utf-8"));
    try (CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = httpclient.execute(httpPost)) {
      log.debug("Executing request " + httpPost.getRequestLine());
      int responseCode = response.getStatusLine().getStatusCode();
      if (responseCode == HttpURLConnection.HTTP_OK) {
        log.info("Updated " + url + " with " + data);
      } else {
        log.error("Failed to post, response: " + responseCode +
            " (" + response.getStatusLine().getReasonPhrase() + ")");
      }
    }
  }

  public String getSysInfo() throws IOException {
    return getData(this.baseUrl + SYS_INFO_ENDPOINT);
  }

  public String getStory(final String issueId) throws IOException {
    return getData(this.baseUrl + STORIES_ENDPOINT + "/" + issueId);
  }

  public void addComment(final String issueId, final String comment)
      throws IOException {
    log.debug("Posting comment with data: ({},{})", issueId, comment);
    final String url = baseUrl+STORIES_ENDPOINT+"/"+issueId+"/comments";
    final String escapedComment = comment.replace("\n", "\\n");
    final String json =
        "{\"story_id\":\"" + issueId + "\",\"content\":\"" +
        escapedComment + "\"}";

    postData(url, json);
  }
}
