/*
 * 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.dao;

import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.exceptions.DlabException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.mongodb.client.FindIterable;
import com.mongodb.client.model.Projections;
import org.bson.Document;
import org.keycloak.representations.AccessTokenResponse;

import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import static com.epam.dlab.backendapi.dao.MongoCollections.ROLES;
import static com.mongodb.client.model.Filters.and;
import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Filters.gte;
import static com.mongodb.client.model.Filters.ne;
import static com.mongodb.client.model.Projections.exclude;
import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.include;

/**
 * DAO write the attempt of user login into DLab.
 */
@Singleton
public class SecurityDAO extends BaseDAO {
	private static final String SECURITY_COLLECTION = "security";
	private static final String TOKEN_RESPONSE = "tokenResponse";
	private static final String LAST_ACCESS = "last_access";

	@Inject
	private SelfServiceApplicationConfiguration conf;

	/**
	 * Return the roles or throw exception if roles collection does not exists.
	 */
	public FindIterable<Document> getRoles() {
		if (!collectionExists(ROLES)) {
			throw new DlabException("Collection \"" + ROLES + "\" does not exists.");
		}
		return find(ROLES, ne(ID, "_Example"), fields(exclude("description")));
	}

	public Map<String, Set<String>> getGroups() {
		return stream(find("userGroups"))
				.collect(Collectors.toMap(d -> d.getString(ID).toLowerCase(), this::toUsers));

	}

	public void saveUser(String userName, AccessTokenResponse accessTokenResponse) {
		updateOne(SECURITY_COLLECTION, eq(ID, userName),
				new Document(SET,
						new Document()
								.append(ID, userName)
								.append("created", new Date())
								.append(LAST_ACCESS, new Date())
								.append(TOKEN_RESPONSE, convertToBson(accessTokenResponse))),
				true);
	}

	public void updateUser(String userName, AccessTokenResponse accessTokenResponse) {
		updateOne(SECURITY_COLLECTION, eq(ID, userName),
				new Document(SET,
						new Document()
								.append(ID, userName)
								.append(LAST_ACCESS, new Date())
								.append(TOKEN_RESPONSE, convertToBson(accessTokenResponse))));
	}

	public Optional<UserInfo> getUser(String token) {
		return Optional.ofNullable(mongoService.getCollection(SECURITY_COLLECTION)
				.findOneAndUpdate(and(eq(TOKEN_RESPONSE + ".access_token", token), gte(LAST_ACCESS,
						new Date(new Date().getTime() - conf.getInactiveUserTimeoutMillSec()))), new Document("$set",
						new Document(LAST_ACCESS, new Date()))))
				.map(d -> new UserInfo(d.getString(ID), token));
	}


	public Optional<AccessTokenResponse> getTokenResponse(String user) {
		return findOne(SECURITY_COLLECTION, eq(ID, user), Projections.fields(include(TOKEN_RESPONSE)))
				.map(d -> convertFromDocument((Document) d.get(TOKEN_RESPONSE), AccessTokenResponse.class));
	}

	@SuppressWarnings("unchecked")
	private Set<String> toUsers(Document d) {
		final Object users = d.get("users");
		return users == null ? Collections.emptySet() :
				new HashSet<>(((List<String>) users).stream().map(String::toLowerCase).collect(Collectors.toList()));
	}
}
