// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/modules/configuration/dao/SonarServerConfigurationDao.java
// public interface SonarServerConfigurationDao {
// 
//     SonarServerConfiguration getConfiguration();
// 
// }
// 
// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/modules/configuration/domain/SonarServerConfiguration.java
// public class SonarServerConfiguration {
//     private String url;
//     private String token;
//     private String organization;
// 
//     public SonarServerConfiguration() {
//     }
// 
//     public SonarServerConfiguration(final String url, final String token, final String organization) {
//         this.url = url;
//         this.token = token;
//         this.organization = organization;
//     }
// 
//     public String getUrl() {
//         return url;
//     }
// 
//     public String getToken() {
//         return token;
//     }
// 
//     public String getOrganization() {
//         return organization;
//     }
// 
//     @Override
//     public String toString() {
//         return "SonarServerConfiguration{" +
//                 "url='" + url + '\'' +
//                 ", token='" + token + '\'' +
//                 ", organization='" + organization + '\'' +
//                 '}';
//     }
// }
// 
// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/modules/configuration/domain/sonar/SonarAuthenticationResponse.java
// public final class SonarAuthenticationResponse {
// 
//     private boolean valid;
// 
//     @JsonCreator
//     public SonarAuthenticationResponse(@JsonProperty(value = "valid") boolean valid) {
//         this.valid = valid;
//     }
// 
//     public boolean isValid() {
//         return valid;
//     }
// 
//     @Override
//     public String toString() {
//         return "SonarAuthenticationResponse{" +
//                 "valid=" + valid +
//                 '}';
//     }
// }
// 
// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/modules/configuration/domain/sonar/SonarServerStatus.java
// public final class SonarServerStatus {
// 
//     public enum Key {
//         UP,
//         UNAUTHORIZED,
//         CONNECTION_ERROR,
//         UNKNOWN_ERROR
//     }
// 
//     public static final String STATUS_UP = "UP";
// 
//     private final String id;
//     private final String version;
//     private final String status;
//     private final String message;
// 
//     @JsonCreator
//     public SonarServerStatus(@JsonProperty("id") String id, @JsonProperty("version") String version, @JsonProperty("status") String status, @JsonProperty("message") final String message) {
//         this.id = id;
//         this.version = version;
//         this.status = status;
//         this.message = message;
//     }
// 
//     public SonarServerStatus(final Key status, final String message) {
//         this(null, null, status.name(), message);
//     }
// 
//     public SonarServerStatus(final Key status) {
//         this(null, null, status.name(), null);
//     }
// 
//     public String getId() {
//         return id;
//     }
// 
//     public String getVersion() {
//         return version;
//     }
// 
//     public String getStatus() {
//         return status;
//     }
// 
//     public String getMessage() {
//         return message;
//     }
// }
// 
// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/util/ApiHttpUtils.java
// public final class ApiHttpUtils {
// 
//     private ApiHttpUtils() {
//     }
// 
//     public static HttpHeaders getHeaders(String token) {
//         HttpHeaders headers = new HttpHeaders();
//         String creds = new String(Base64.encodeBase64((token + ":").getBytes()));
//         headers.add("Authorization", "Basic " + creds);
//         headers.add("Accept", "application/json");
//         return headers;
//     }
// 
// }


import com.thepracticaldeveloper.devgame.modules.configuration.dao.SonarServerConfigurationDao;
import com.thepracticaldeveloper.devgame.modules.configuration.domain.SonarServerConfiguration;
import com.thepracticaldeveloper.devgame.modules.configuration.domain.sonar.SonarAuthenticationResponse;
import com.thepracticaldeveloper.devgame.modules.configuration.domain.sonar.SonarServerStatus;
import com.thepracticaldeveloper.devgame.util.ApiHttpUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
package com.thepracticaldeveloper.devgame.modules.configuration.service;


@Service
final class SonarServerConfigurationServiceImpl implements SonarServerConfigurationService {

    private static final Log log = LogFactory.getLog(SonarServerConfigurationServiceImpl.class);
    private static final String API_SYSTEM_STATUS = "/api/system/status";
    private static final String API_AUTHENTICATION_VALIDATE = "/api/authentication/validate";

    private SonarServerConfigurationDao sonarServerConfigurationDao;
    private RestTemplate restTemplate;

    @Autowired
    public SonarServerConfigurationServiceImpl(final SonarServerConfigurationDao sonarServerConfigurationDao, final RestTemplate restTemplate) {
        this.sonarServerConfigurationDao = sonarServerConfigurationDao;
        this.restTemplate = restTemplate;
    }

    /**
     * Checks the current status of the server and the version running on it.
     * It also detects if the server is not reachable.
     *
     * @param config The configuration for Sonar Server
     * @return the response from server
     */
    @Override
// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/modules/configuration/dao/SonarServerConfigurationDao.java
// public interface SonarServerConfigurationDao {
// 
//     SonarServerConfiguration getConfiguration();
// 
// }
// 
// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/modules/configuration/domain/SonarServerConfiguration.java
// public class SonarServerConfiguration {
//     private String url;
//     private String token;
//     private String organization;
// 
//     public SonarServerConfiguration() {
//     }
// 
//     public SonarServerConfiguration(final String url, final String token, final String organization) {
//         this.url = url;
//         this.token = token;
//         this.organization = organization;
//     }
// 
//     public String getUrl() {
//         return url;
//     }
// 
//     public String getToken() {
//         return token;
//     }
// 
//     public String getOrganization() {
//         return organization;
//     }
// 
//     @Override
//     public String toString() {
//         return "SonarServerConfiguration{" +
//                 "url='" + url + '\'' +
//                 ", token='" + token + '\'' +
//                 ", organization='" + organization + '\'' +
//                 '}';
//     }
// }
// 
// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/modules/configuration/domain/sonar/SonarAuthenticationResponse.java
// public final class SonarAuthenticationResponse {
// 
//     private boolean valid;
// 
//     @JsonCreator
//     public SonarAuthenticationResponse(@JsonProperty(value = "valid") boolean valid) {
//         this.valid = valid;
//     }
// 
//     public boolean isValid() {
//         return valid;
//     }
// 
//     @Override
//     public String toString() {
//         return "SonarAuthenticationResponse{" +
//                 "valid=" + valid +
//                 '}';
//     }
// }
// 
// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/modules/configuration/domain/sonar/SonarServerStatus.java
// public final class SonarServerStatus {
// 
//     public enum Key {
//         UP,
//         UNAUTHORIZED,
//         CONNECTION_ERROR,
//         UNKNOWN_ERROR
//     }
// 
//     public static final String STATUS_UP = "UP";
// 
//     private final String id;
//     private final String version;
//     private final String status;
//     private final String message;
// 
//     @JsonCreator
//     public SonarServerStatus(@JsonProperty("id") String id, @JsonProperty("version") String version, @JsonProperty("status") String status, @JsonProperty("message") final String message) {
//         this.id = id;
//         this.version = version;
//         this.status = status;
//         this.message = message;
//     }
// 
//     public SonarServerStatus(final Key status, final String message) {
//         this(null, null, status.name(), message);
//     }
// 
//     public SonarServerStatus(final Key status) {
//         this(null, null, status.name(), null);
//     }
// 
//     public String getId() {
//         return id;
//     }
// 
//     public String getVersion() {
//         return version;
//     }
// 
//     public String getStatus() {
//         return status;
//     }
// 
//     public String getMessage() {
//         return message;
//     }
// }
// 
// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/util/ApiHttpUtils.java
// public final class ApiHttpUtils {
// 
//     private ApiHttpUtils() {
//     }
// 
//     public static HttpHeaders getHeaders(String token) {
//         HttpHeaders headers = new HttpHeaders();
//         String creds = new String(Base64.encodeBase64((token + ":").getBytes()));
//         headers.add("Authorization", "Basic " + creds);
//         headers.add("Accept", "application/json");
//         return headers;
//     }
// 
// }


// Path: sonar-connector/src/main/java/com/thepracticaldeveloper/devgame/modules/configuration/service/SonarServerConfigurationServiceImpl.java
import com.thepracticaldeveloper.devgame.modules.configuration.dao.SonarServerConfigurationDao;
import com.thepracticaldeveloper.devgame.modules.configuration.domain.SonarServerConfiguration;
import com.thepracticaldeveloper.devgame.modules.configuration.domain.sonar.SonarAuthenticationResponse;
import com.thepracticaldeveloper.devgame.modules.configuration.domain.sonar.SonarServerStatus;
import com.thepracticaldeveloper.devgame.util.ApiHttpUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

package com.thepracticaldeveloper.devgame.modules.configuration.service;


@Service
final class SonarServerConfigurationServiceImpl implements SonarServerConfigurationService {

    private static final Log log = LogFactory.getLog(SonarServerConfigurationServiceImpl.class);
    private static final String API_SYSTEM_STATUS = "/api/system/status";
    private static final String API_AUTHENTICATION_VALIDATE = "/api/authentication/validate";

    private SonarServerConfigurationDao sonarServerConfigurationDao;
    private RestTemplate restTemplate;

    @Autowired
    public SonarServerConfigurationServiceImpl(final SonarServerConfigurationDao sonarServerConfigurationDao, final RestTemplate restTemplate) {
        this.sonarServerConfigurationDao = sonarServerConfigurationDao;
        this.restTemplate = restTemplate;
    }

    /**
     * Checks the current status of the server and the version running on it.
     * It also detects if the server is not reachable.
     *
     * @param config The configuration for Sonar Server
     * @return the response from server
     */
    @Override
    public SonarServerStatus checkServerDetails(final SonarServerConfiguration config) {