/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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 org.onosproject.protocol.rest.ctl;

import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.onlab.packet.IpAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.protocol.rest.RestSBController;
import org.onosproject.protocol.rest.RestSBDevice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * The implementation of RestSBController.
 */
@Component(immediate = true)
@Service
public class RestSBControllerImpl implements RestSBController {

    private static final Logger log =
            LoggerFactory.getLogger(RestSBControllerImpl.class);
    private static final String XML = "xml";
    private static final String JSON = "json";
    private static final String DOUBLESLASH = "//";
    private static final String COLON = ":";
    private static final int STATUS_OK = Response.Status.OK.getStatusCode();
    private static final int STATUS_CREATED = Response.Status.CREATED.getStatusCode();
    private static final int STATUS_ACCEPTED = Response.Status.ACCEPTED.getStatusCode();
    private static final String HTTPS = "https";
    private static final String AUTHORIZATION_PROPERTY = "authorization";
    private static final String BASIC_AUTH_PREFIX = "Basic ";

    private final Map<DeviceId, RestSBDevice> deviceMap = new ConcurrentHashMap<>();
    private final Map<DeviceId, Client> clientMap = new ConcurrentHashMap<>();

    @Activate
    public void activate() {
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        clientMap.clear();
        deviceMap.clear();
        log.info("Stopped");
    }

    @Override
    public Map<DeviceId, RestSBDevice> getDevices() {
        return ImmutableMap.copyOf(deviceMap);
    }

    @Override
    public RestSBDevice getDevice(DeviceId deviceInfo) {
        return deviceMap.get(deviceInfo);
    }

    @Override
    public RestSBDevice getDevice(IpAddress ip, int port) {
        return deviceMap.values().stream().filter(v -> v.ip().equals(ip)
                && v.port() == port).findFirst().get();
    }

    @Override
    public void addDevice(RestSBDevice device) {
        if (!deviceMap.containsKey(device.deviceId())) {
            Client client = ignoreSslClient();
            if (device.username() != null) {
                String username = device.username();
                String password = device.password() == null ? "" : device.password();
                authenticate(client, username, password);
            }
            clientMap.put(device.deviceId(), client);
            deviceMap.put(device.deviceId(), device);
        } else {
            log.warn("Trying to add a device that is already existing {}", device.deviceId());
        }

    }

    @Override
    public void removeDevice(DeviceId deviceId) {
        clientMap.remove(deviceId);
        deviceMap.remove(deviceId);
    }

    @Override
    public boolean post(DeviceId device, String request, InputStream payload, String mediaType) {
        Response response = getResponse(device, request, payload, mediaType);
        return checkReply(response);
    }

    @Override
    public <T> T post(DeviceId device, String request, InputStream payload,
                      String mediaType, Class<T> responseClass) {
        Response response = getResponse(device, request, payload, mediaType);
        if (response.hasEntity()) {
            return response.readEntity(responseClass);
        }
        log.error("Response from device {} for request {} contains no entity", device, request);
        return null;
    }

    private Response getResponse(DeviceId device, String request, InputStream payload, String mediaType) {
        WebTarget wt = getWebTarget(device, request);

        Response response = null;
        if (payload != null) {
            try {
                response = wt.request(mediaType)
                        .post(Entity.entity(IOUtils.toString(payload, StandardCharsets.UTF_8), mediaType));
            } catch (IOException e) {
                log.error("Cannot do POST {} request on device {} because can't read payload",
                          request, device);
            }
        } else {
            response = wt.request(mediaType).post(Entity.entity(null, mediaType));
        }
        return response;
    }

    @Override
    public boolean put(DeviceId device, String request, InputStream payload, String mediaType) {

        WebTarget wt = getWebTarget(device, request);
        Response response = null;
        if (payload != null) {
            try {
                response = wt.request(mediaType)
                        .put(Entity.entity(IOUtils.toString(payload, StandardCharsets.UTF_8), mediaType));
            } catch (IOException e) {
                log.error("Cannot do PUT {} request on device {} because can't read payload",
                          request, device);
            }
        } else {
            response = wt.request(mediaType).put(Entity.entity(null, mediaType));
        }
        return checkReply(response);
    }

    @Override
    public InputStream get(DeviceId device, String request, String mediaType) {
        WebTarget wt = getWebTarget(device, request);
        String type;
        switch (mediaType) {
            case XML:
                type = MediaType.APPLICATION_XML;
                break;
            case JSON:
                type = MediaType.APPLICATION_JSON;
                break;
            default:
                throw new IllegalArgumentException("Unsupported media type " + mediaType);

        }

        Response s = wt.request(type).get();
        if (checkReply(s)) {
            return new ByteArrayInputStream(wt.request(type)
                                                    .get(String.class).getBytes(StandardCharsets.UTF_8));
        }
        return null;
    }

    @Override
    public boolean patch(DeviceId device, String request, InputStream payload, String mediaType) {
        try {
            log.debug("Url request {} ", getUrlString(device, request));
            HttpPatch httprequest = new HttpPatch(getUrlString(device, request));
            if (deviceMap.get(device).username() != null) {
                String pwd = deviceMap.get(device).password() == null ? "" : COLON + deviceMap.get(device).password();
                String userPassword = deviceMap.get(device).username() + pwd;
                String base64string = Base64.getEncoder().encodeToString(userPassword.getBytes(StandardCharsets.UTF_8));
                httprequest.addHeader(AUTHORIZATION_PROPERTY, BASIC_AUTH_PREFIX + base64string);
            }
            if (payload != null) {
                StringEntity input = new StringEntity(IOUtils.toString(payload, StandardCharsets.UTF_8));
                input.setContentType(mediaType);
                httprequest.setEntity(input);
            }
            CloseableHttpClient httpClient;
            if (deviceMap.containsKey(device) && deviceMap.get(device).protocol().equals(HTTPS)) {
                httpClient = getApacheSslBypassClient();
            } else {
                httpClient = HttpClients.createDefault();
            }
            int responseStatusCode = httpClient
                    .execute(httprequest)
                    .getStatusLine()
                    .getStatusCode();
            return checkStatusCode(responseStatusCode);
        } catch (IOException | NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
            log.error("Cannot do PATCH {} request on device {}",
                      request, device, e);
        }
        return false;
    }

    @Override
    public boolean delete(DeviceId device, String request, InputStream payload, String mediaType) {
        WebTarget wt = getWebTarget(device, request);

        // FIXME: do we need to delete an entry by enclosing data in DELETE request?
        // wouldn't it be nice to use PUT to implement the similar concept?
        Response response = wt.request(mediaType).delete();

        return checkReply(response);
    }

    private void authenticate(Client client, String username, String password) {
        client.register(HttpAuthenticationFeature.basic(username, password));
    }

    private WebTarget getWebTarget(DeviceId device, String request) {
        log.debug("Sending request to URL {} ", getUrlString(device, request));
        return clientMap.get(device).target(getUrlString(device, request));
    }

    //FIXME security issue: this trusts every SSL certificate, even if is self-signed. Also deprecated methods.
    private CloseableHttpClient getApacheSslBypassClient() throws NoSuchAlgorithmException,
            KeyManagementException, KeyStoreException {
        return HttpClients.custom().
                setHostnameVerifier(new AllowAllHostnameVerifier()).
                setSslcontext(new SSLContextBuilder()
                                      .loadTrustMaterial(null, (arg0, arg1) -> true)
                                      .build()).build();
    }

    private String getUrlString(DeviceId device, String request) {
        if (deviceMap.get(device).url() != null) {
            return deviceMap.get(device).protocol() + COLON + DOUBLESLASH
                    + deviceMap.get(device).url() + request;
        } else {
            return deviceMap.get(device).protocol() + COLON +
                    DOUBLESLASH +
                    deviceMap.get(device).ip().toString() +
                    COLON + deviceMap.get(device).port() + request;
        }
    }

    private boolean checkReply(Response response) {
        if (response != null) {
            return checkStatusCode(response.getStatus());
        }
        log.error("Null reply from device");
        return false;
    }

    private boolean checkStatusCode(int statusCode) {
        if (statusCode == STATUS_OK ||
                statusCode == STATUS_CREATED ||
                statusCode == STATUS_ACCEPTED) {
            return true;
        } else {
            log.error("Failed request, HTTP error code : "
                              + statusCode);
            return false;
        }
    }

    private Client ignoreSslClient() {
        SSLContext sslcontext = null;

        try {
            sslcontext = SSLContext.getInstance("TLS");
            sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            } }, new java.security.SecureRandom());
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }

        return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier((s1, s2) -> true).build();
    }
}
