/*
 * 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.datalab.backendapi.service.impl;

import com.epam.datalab.auth.UserInfo;
import com.epam.datalab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.datalab.backendapi.dao.ExploratoryDAO;
import com.epam.datalab.backendapi.domain.BillingReport;
import com.epam.datalab.backendapi.domain.EndpointDTO;
import com.epam.datalab.backendapi.domain.ProjectDTO;
import com.epam.datalab.backendapi.domain.ProjectEndpointDTO;
import com.epam.datalab.backendapi.domain.RequestId;
import com.epam.datalab.backendapi.resources.dto.HealthStatusEnum;
import com.epam.datalab.backendapi.resources.dto.HealthStatusPageDTO;
import com.epam.datalab.backendapi.resources.dto.ProjectInfrastructureInfo;
import com.epam.datalab.backendapi.roles.RoleType;
import com.epam.datalab.backendapi.roles.UserRoles;
import com.epam.datalab.backendapi.service.BillingService;
import com.epam.datalab.backendapi.service.EndpointService;
import com.epam.datalab.backendapi.service.InfrastructureInfoService;
import com.epam.datalab.backendapi.service.ProjectService;
import com.epam.datalab.backendapi.util.RequestBuilder;
import com.epam.datalab.constants.ServiceConsts;
import com.epam.datalab.dto.InfrastructureMetaInfoDTO;
import com.epam.datalab.dto.UserInstanceDTO;
import com.epam.datalab.dto.aws.edge.EdgeInfoAws;
import com.epam.datalab.dto.azure.edge.EdgeInfoAzure;
import com.epam.datalab.dto.base.edge.EdgeInfo;
import com.epam.datalab.dto.computational.UserComputationalResource;
import com.epam.datalab.dto.gcp.edge.EdgeInfoGcp;
import com.epam.datalab.dto.status.EnvResource;
import com.epam.datalab.dto.status.EnvResourceList;
import com.epam.datalab.rest.client.RESTService;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.jcabi.manifests.Manifests;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
public class InfrastructureInfoServiceImpl implements InfrastructureInfoService {

    private static final String RELEASE_NOTES_FORMAT = "https://github.com/apache/incubator-datalab/blob/%s/RELEASE_NOTES.md";
    private static final String PERMISSION_VIEW = "/api/bucket/view";
    private static final String PERMISSION_UPLOAD = "/api/bucket/upload";
    private static final String PERMISSION_DOWNLOAD = "/api/bucket/download";
    private static final String PERMISSION_DELETE = "/api/bucket/delete";
    private static final String INFRASTRUCTURE_STATUS = "infrastructure/status";

    private final ExploratoryDAO expDAO;
    private final SelfServiceApplicationConfiguration configuration;
    private final ProjectService projectService;
    private final EndpointService endpointService;
    private final BillingService billingService;
    private final RequestBuilder requestBuilder;
    private final RESTService provisioningService;
    private final RequestId requestId;


    @Inject
    public InfrastructureInfoServiceImpl(ExploratoryDAO expDAO, SelfServiceApplicationConfiguration configuration, ProjectService projectService,
                                         EndpointService endpointService, BillingService billingService, RequestBuilder requestBuilder,
                                         @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService, RequestId requestId) {
        this.expDAO = expDAO;
        this.configuration = configuration;
        this.projectService = projectService;
        this.endpointService = endpointService;
        this.billingService = billingService;
        this.requestBuilder = requestBuilder;
        this.provisioningService = provisioningService;
        this.requestId = requestId;
    }

    @Override
    public List<ProjectInfrastructureInfo> getUserResources(UserInfo user) {
        log.debug("Loading list of provisioned resources for user {}", user);
        List<EndpointDTO> allEndpoints = endpointService.getEndpoints();
        return projectService.getUserProjects(user, Boolean.FALSE)
                .stream()
                .map(p -> {
                    List<UserInstanceDTO> exploratories = expDAO.findExploratories(user.getName(), p.getName());
                    return ProjectInfrastructureInfo.builder()
                            .project(p.getName())
                            .billingQuoteUsed(billingService.getBillingProjectQuoteUsed(p.getName()))
                            .shared(getSharedInfo(p.getName()))
                            .exploratory(exploratories)
                            .exploratoryBilling(getExploratoryBillingData(exploratories))
                            .endpoints(getEndpoints(allEndpoints, p))
                            .build();
                })
                .collect(Collectors.toList());
    }

    @Override
    public HealthStatusPageDTO getHeathStatus(UserInfo userInfo) {
        log.debug("Request the status of resources for user {}", userInfo.getName());
        return HealthStatusPageDTO.builder()
                .status(HealthStatusEnum.OK.toString())
                .listResources(Collections.emptyList())
                .billingEnabled(configuration.isBillingSchedulerEnabled())
                .auditEnabled(configuration.isAuditEnabled())
                .projectAdmin(UserRoles.isProjectAdmin(userInfo))
                .admin(UserRoles.isAdmin(userInfo))
                .projectAssigned(projectService.isAnyProjectAssigned(userInfo))
                .bucketBrowser(HealthStatusPageDTO.BucketBrowser.builder()
                        .view(checkAccess(userInfo, PERMISSION_VIEW))
                        .upload(checkAccess(userInfo, PERMISSION_UPLOAD))
                        .download(checkAccess(userInfo, PERMISSION_DOWNLOAD))
                        .delete(checkAccess(userInfo, PERMISSION_DELETE))
                        .build())
                .build();
    }

    @Override
    public InfrastructureMetaInfoDTO getInfrastructureMetaInfo() {
        final String branch = Manifests.read("GIT-Branch");
        return InfrastructureMetaInfoDTO.builder()
                .branch(branch)
                .commit(Manifests.read("GIT-Commit"))
                .version(Manifests.read("DataLab-Version"))
                .releaseNotes(String.format(RELEASE_NOTES_FORMAT, branch))
                .build();
    }

    @Override
    public void updateInfrastructureStatuses(UserInfo user, String endpoint, List<EnvResource> hostInstances, List<EnvResource> clusterInstances) {
        EnvResourceList envResourceList = new EnvResourceList()
                .withClusterList(clusterInstances)
                .withHostList(hostInstances);

        EndpointDTO endpointDTO = endpointService.get(endpoint);
        String uuid = provisioningService.post(endpointDTO.getUrl() + INFRASTRUCTURE_STATUS, user.getAccessToken(),
                requestBuilder.newInfrastructureStatus(user.getName(), endpointDTO.getCloudProvider(), envResourceList),
                String.class);
        requestId.put(user.getName(), uuid);
    }

    private List<BillingReport> getExploratoryBillingData(List<UserInstanceDTO> exploratories) {
        return exploratories
                .stream()
                .map(exp -> billingService.getExploratoryBillingData(exp.getProject(), exp.getEndpoint(),
                        exp.getExploratoryName(), exp.getResources()
                                .stream()
                                .map(UserComputationalResource::getComputationalName)
                                .collect(Collectors.toList())
                ))
                .collect(Collectors.toList());
    }

    private List<EndpointDTO> getEndpoints(List<EndpointDTO> allEndpoints, ProjectDTO projectDTO) {
        return allEndpoints
                .stream()
                .filter(endpoint -> projectDTO.getEndpoints()
                        .stream()
                        .anyMatch(endpoint1 -> endpoint1.getName().equals(endpoint.getName())))
                .collect(Collectors.toList());
    }

    private Map<String, Map<String, String>> getSharedInfo(String name) {
        return projectService.get(name).getEndpoints()
                .stream()
                .collect(Collectors.toMap(ProjectEndpointDTO::getName, this::getSharedInfo));
    }

    private Map<String, String> getSharedInfo(ProjectEndpointDTO endpointDTO) {
        Optional<EdgeInfo> edgeInfo = Optional.ofNullable(endpointDTO.getEdgeInfo());
        if (!edgeInfo.isPresent()) {
            return Collections.emptyMap();
        }
        EdgeInfo edge = edgeInfo.get();
        Map<String, String> shared = new HashMap<>();

        shared.put("status", endpointDTO.getStatus().toString());
        shared.put("edge_node_ip", edge.getPublicIp());
        if (edge instanceof EdgeInfoAws) {
            EdgeInfoAws edgeInfoAws = (EdgeInfoAws) edge;
            shared.put("user_own_bicket_name", edgeInfoAws.getUserOwnBucketName());
            shared.put("shared_bucket_name", edgeInfoAws.getSharedBucketName());
        } else if (edge instanceof EdgeInfoAzure) {
            EdgeInfoAzure edgeInfoAzure = (EdgeInfoAzure) edge;
            shared.put("user_container_name", edgeInfoAzure.getUserContainerName());
            shared.put("shared_container_name", edgeInfoAzure.getSharedContainerName());
            shared.put("user_storage_account_name", edgeInfoAzure.getUserStorageAccountName());
            shared.put("shared_storage_account_name", edgeInfoAzure.getSharedStorageAccountName());
            shared.put("datalake_name", edgeInfoAzure.getDataLakeName());
            shared.put("datalake_user_directory_name", edgeInfoAzure.getDataLakeDirectoryName());
            shared.put("datalake_shared_directory_name", edgeInfoAzure.getDataLakeSharedDirectoryName());
        } else if (edge instanceof EdgeInfoGcp) {
            EdgeInfoGcp edgeInfoGcp = (EdgeInfoGcp) edge;
            shared.put("user_own_bucket_name", edgeInfoGcp.getUserOwnBucketName());
            shared.put("shared_bucket_name", edgeInfoGcp.getSharedBucketName());
        }

        return shared;
    }

    private boolean checkAccess(UserInfo userInfo, String permission) {
        return UserRoles.checkAccess(userInfo, RoleType.PAGE, permission, userInfo.getRoles());
    }
}
