// Path: src/main/java/se/bjurr/gitchangelog/api/exceptions/GitChangelogIntegrationException.java
// public class GitChangelogIntegrationException extends Exception {
// 
//   private static final long serialVersionUID = 4249741847365803709L;
// 
//   public GitChangelogIntegrationException(String message, Throwable throwable) {
//     super(message, throwable);
//   }
// 
//   public GitChangelogIntegrationException(String message) {
//     super(message);
//   }
// }
// 
// Path: src/main/java/se/bjurr/gitchangelog/internal/integrations/rest/RestClient.java
// public class RestClient {
//   private static Logger logger = getLogger(RestClient.class);
//   private static RestClient mockedRestClient;
//   private final Map<String, Optional<String>> urlCache = new ConcurrentHashMap<>();
//   private String basicAuthString;
//   private String bearer;
//   private Map<String, String> headers;
// 
//   public RestClient() {}
// 
//   public RestClient withBasicAuthCredentials(final String username, final String password) {
//     try {
//       this.basicAuthString =
//           Base64.getEncoder().encodeToString((username + ":" + password).getBytes("UTF-8"));
//     } catch (final UnsupportedEncodingException e) {
//       throw new RuntimeException(e);
//     }
//     return this;
//   }
// 
//   public RestClient withTokenAuthCredentials(final String token) {
//     this.basicAuthString = token;
//     return this;
//   }
// 
//   public RestClient withBearer(final String bearer) {
//     this.bearer = bearer;
//     return this;
//   }
// 
//   public RestClient withHeaders(final Map<String, String> headers) {
//     this.headers = headers;
//     return this;
//   }
// 
//   public Optional<String> get(final String url) throws GitChangelogIntegrationException {
//     try {
//       if (!this.urlCache.containsKey(url)) {
//         final Optional<String> content = RestClient.this.doGet(url);
//         this.urlCache.put(url, content);
//       }
//       return this.urlCache.get(url);
//     } catch (final Exception e) {
//       throw new GitChangelogIntegrationException("Problems invoking " + url, e);
//     }
//   }
// 
//   private Optional<String> doGet(final String urlParam) {
//     final String response = null;
//     HttpURLConnection conn = null;
//     try {
//       logger.info("GET:\n" + urlParam);
//       final URL url = new URL(urlParam);
//       conn = this.openConnection(url);
//       conn.setRequestProperty("Content-Type", "application/json");
//       conn.setRequestProperty("Accept", "application/json");
//       if (this.headers != null) {
//         for (final Entry<String, String> entry : this.headers.entrySet()) {
//           conn.setRequestProperty(entry.getKey(), entry.getValue());
//         }
//       }
//       if (this.bearer != null) {
//         conn.setRequestProperty("Authorization", "Bearer " + this.bearer);
//       } else if (this.basicAuthString != null) {
//         conn.setRequestProperty("Authorization", "Basic " + this.basicAuthString);
//       }
//       return Optional.of(this.getResponse(conn));
//     } catch (final Exception e) {
//       logger.error("Got:\n" + response, e);
//       return Optional.empty();
//     } finally {
//       if (conn != null) {
//         conn.disconnect();
//       }
//     }
//   }
// 
//   protected HttpURLConnection openConnection(final URL url) throws Exception {
//     if (mockedRestClient == null) {
//       return (HttpURLConnection) url.openConnection();
//     }
//     return mockedRestClient.openConnection(url);
//   }
// 
//   protected String getResponse(final HttpURLConnection conn) throws Exception {
//     if (mockedRestClient == null) {
//       final InputStream inputStream = conn.getInputStream();
//       InputStreamReader inputStreamReader =
//           new InputStreamReader(inputStream, StandardCharsets.UTF_8);
//       BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
//       return bufferedReader.readLine();
//     }
//     return mockedRestClient.getResponse(conn);
//   }
// 
//   public static void mock(final RestClient mock) {
//     mockedRestClient = mock;
//   }
// }


import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.Map;
import java.util.Optional;
import se.bjurr.gitchangelog.api.exceptions.GitChangelogIntegrationException;
import se.bjurr.gitchangelog.internal.integrations.rest.RestClient;
package se.bjurr.gitchangelog.internal.integrations.redmine;


public class DefaultRedmineClient extends RedmineClient {

  private RestClient client;

  public DefaultRedmineClient(final String api) {
    super(api);
    this.client = new RestClient();
  }

  @Override
  public RedmineClient withBasicCredentials(final String username, final String password) {
    this.client = this.client.withBasicAuthCredentials(username, password);
    return this;
  }

  @Override
  public RedmineClient withTokenCredentials(final String token) {
    String authToken;
    try {
      authToken = Base64.getEncoder().encodeToString((token + ":changelog").getBytes("UTF-8"));
    } catch (final UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
    this.client = this.client.withTokenAuthCredentials(authToken);
    return this;
  }

  @Override
  public RedmineClient withHeaders(final Map<String, String> headers) {
    this.client = this.client.withHeaders(headers);
    return this;
  }

  @Override
  public Optional<RedmineIssue> getIssue(final String issue)
// Path: src/main/java/se/bjurr/gitchangelog/api/exceptions/GitChangelogIntegrationException.java
// public class GitChangelogIntegrationException extends Exception {
// 
//   private static final long serialVersionUID = 4249741847365803709L;
// 
//   public GitChangelogIntegrationException(String message, Throwable throwable) {
//     super(message, throwable);
//   }
// 
//   public GitChangelogIntegrationException(String message) {
//     super(message);
//   }
// }
// 
// Path: src/main/java/se/bjurr/gitchangelog/internal/integrations/rest/RestClient.java
// public class RestClient {
//   private static Logger logger = getLogger(RestClient.class);
//   private static RestClient mockedRestClient;
//   private final Map<String, Optional<String>> urlCache = new ConcurrentHashMap<>();
//   private String basicAuthString;
//   private String bearer;
//   private Map<String, String> headers;
// 
//   public RestClient() {}
// 
//   public RestClient withBasicAuthCredentials(final String username, final String password) {
//     try {
//       this.basicAuthString =
//           Base64.getEncoder().encodeToString((username + ":" + password).getBytes("UTF-8"));
//     } catch (final UnsupportedEncodingException e) {
//       throw new RuntimeException(e);
//     }
//     return this;
//   }
// 
//   public RestClient withTokenAuthCredentials(final String token) {
//     this.basicAuthString = token;
//     return this;
//   }
// 
//   public RestClient withBearer(final String bearer) {
//     this.bearer = bearer;
//     return this;
//   }
// 
//   public RestClient withHeaders(final Map<String, String> headers) {
//     this.headers = headers;
//     return this;
//   }
// 
//   public Optional<String> get(final String url) throws GitChangelogIntegrationException {
//     try {
//       if (!this.urlCache.containsKey(url)) {
//         final Optional<String> content = RestClient.this.doGet(url);
//         this.urlCache.put(url, content);
//       }
//       return this.urlCache.get(url);
//     } catch (final Exception e) {
//       throw new GitChangelogIntegrationException("Problems invoking " + url, e);
//     }
//   }
// 
//   private Optional<String> doGet(final String urlParam) {
//     final String response = null;
//     HttpURLConnection conn = null;
//     try {
//       logger.info("GET:\n" + urlParam);
//       final URL url = new URL(urlParam);
//       conn = this.openConnection(url);
//       conn.setRequestProperty("Content-Type", "application/json");
//       conn.setRequestProperty("Accept", "application/json");
//       if (this.headers != null) {
//         for (final Entry<String, String> entry : this.headers.entrySet()) {
//           conn.setRequestProperty(entry.getKey(), entry.getValue());
//         }
//       }
//       if (this.bearer != null) {
//         conn.setRequestProperty("Authorization", "Bearer " + this.bearer);
//       } else if (this.basicAuthString != null) {
//         conn.setRequestProperty("Authorization", "Basic " + this.basicAuthString);
//       }
//       return Optional.of(this.getResponse(conn));
//     } catch (final Exception e) {
//       logger.error("Got:\n" + response, e);
//       return Optional.empty();
//     } finally {
//       if (conn != null) {
//         conn.disconnect();
//       }
//     }
//   }
// 
//   protected HttpURLConnection openConnection(final URL url) throws Exception {
//     if (mockedRestClient == null) {
//       return (HttpURLConnection) url.openConnection();
//     }
//     return mockedRestClient.openConnection(url);
//   }
// 
//   protected String getResponse(final HttpURLConnection conn) throws Exception {
//     if (mockedRestClient == null) {
//       final InputStream inputStream = conn.getInputStream();
//       InputStreamReader inputStreamReader =
//           new InputStreamReader(inputStream, StandardCharsets.UTF_8);
//       BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
//       return bufferedReader.readLine();
//     }
//     return mockedRestClient.getResponse(conn);
//   }
// 
//   public static void mock(final RestClient mock) {
//     mockedRestClient = mock;
//   }
// }


// Path: src/main/java/se/bjurr/gitchangelog/internal/integrations/redmine/DefaultRedmineClient.java
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.Map;
import java.util.Optional;
import se.bjurr.gitchangelog.api.exceptions.GitChangelogIntegrationException;
import se.bjurr.gitchangelog.internal.integrations.rest.RestClient;

package se.bjurr.gitchangelog.internal.integrations.redmine;


public class DefaultRedmineClient extends RedmineClient {

  private RestClient client;

  public DefaultRedmineClient(final String api) {
    super(api);
    this.client = new RestClient();
  }

  @Override
  public RedmineClient withBasicCredentials(final String username, final String password) {
    this.client = this.client.withBasicAuthCredentials(username, password);
    return this;
  }

  @Override
  public RedmineClient withTokenCredentials(final String token) {
    String authToken;
    try {
      authToken = Base64.getEncoder().encodeToString((token + ":changelog").getBytes("UTF-8"));
    } catch (final UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
    this.client = this.client.withTokenAuthCredentials(authToken);
    return this;
  }

  @Override
  public RedmineClient withHeaders(final Map<String, String> headers) {
    this.client = this.client.withHeaders(headers);
    return this;
  }

  @Override
  public Optional<RedmineIssue> getIssue(final String issue)
      throws GitChangelogIntegrationException {