/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.epam.dlab.backendapi.service;

import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.SecurityDAO;
import com.epam.dlab.backendapi.util.KeycloakUtil;
import com.epam.dlab.exceptions.DlabException;
import com.google.inject.Inject;
import de.ahus1.keycloak.dropwizard.KeycloakConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.glassfish.jersey.internal.util.Base64;
import org.keycloak.representations.AccessTokenResponse;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;

@Slf4j
public class KeycloakServiceImpl implements KeycloakService {

	private static final String URI = "/realms/%s/protocol/openid-connect/token";
	private final Client httpClient;
	private final KeycloakConfiguration conf;
	private final SecurityDAO securityDAO;
	private final String redirectUri;

	@Inject
	public KeycloakServiceImpl(Client httpClient, SelfServiceApplicationConfiguration conf, SecurityDAO securityDAO) {
		this.httpClient = httpClient;
		this.conf = conf.getKeycloakConfiguration();
		this.securityDAO = securityDAO;
		this.redirectUri = conf.getKeycloakConfiguration().getRedirectUri();
	}

	@Override
	public AccessTokenResponse getToken(String code) {
		return requestToken(accessTokenRequestForm(code));
	}

	@Override
	public AccessTokenResponse refreshToken(String refreshToken) {
		return requestToken(refreshTokenRequestForm(refreshToken));
	}

	@Override
	public AccessTokenResponse generateAccessToken(String refreshToken) {
		AccessTokenResponse tokenResponse = refreshToken(refreshToken);
		final String username = KeycloakUtil.parseToken(tokenResponse.getToken()).getPreferredUsername();
		securityDAO.updateUser(username, tokenResponse);
		return tokenResponse;
	}

	@Override
	public AccessTokenResponse generateServiceAccountToken() {
		return requestToken(serviceAccountRequestForm());
	}

	private AccessTokenResponse requestToken(Form requestForm) {
		final String credentials = Base64.encodeAsString(String.join(":", conf.getResource(),
				String.valueOf(conf.getCredentials().get("secret"))));
		final Response response =
				httpClient.target(conf.getAuthServerUrl() + String.format(URI, conf.getRealm())).request()
				.header(HttpHeaders.AUTHORIZATION, "Basic " + credentials)
				.post(Entity.form(requestForm));
		if (response.getStatusInfo().getFamily() != Response.Status.Family.SUCCESSFUL) {

			log.error("Error getting token:code {}, body {}", response.getStatus(), response.readEntity(String.class));
			throw new DlabException("can not get token");
		}
		return response.readEntity(AccessTokenResponse.class);
	}

	private Form accessTokenRequestForm(String code) {
		return new Form()
				.param("grant_type", "authorization_code")
				.param("code", code)
				.param("redirect_uri", redirectUri);
	}

	private Form refreshTokenRequestForm(String refreshToken) {
		return new Form()
				.param("grant_type", "refresh_token")
				.param("refresh_token", refreshToken);
	}

	private Form serviceAccountRequestForm() {
		return new Form()
				.param("grant_type", "client_credentials");
	}
}
