/*
 * 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 org.apache.sling.cli.impl.nexus;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.sling.cli.impl.http.HttpClientFactory;
import org.apache.sling.cli.impl.nexus.StagingRepository.Status;
import org.jetbrains.annotations.NotNull;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

@Component(service = RepositoryService.class)
public class RepositoryService {
    
    private static final String REPOSITORY_PREFIX = "orgapachesling-";
    private static final Logger LOGGER = LoggerFactory.getLogger(RepositoryService.class);

    private Map<String, LocalRepository> repositories = new HashMap<>();
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    @Reference
    private HttpClientFactory httpClientFactory;

    public List<StagingRepository> list() throws IOException {
        return this.withStagingRepositories( reader -> {
            Gson gson = new Gson();
            return gson.fromJson(reader, StagingRepositories.class).getData().stream()
                    .filter( r -> r.getType() == Status.closed)
                    .filter( r -> r.getRepositoryId().startsWith(REPOSITORY_PREFIX) )
                    .collect(Collectors.toList());            
        });
    }

    public StagingRepository find(int stagingRepositoryId) throws IOException {
        return this.withStagingRepositories( reader -> {
            Gson gson = new Gson();
            return gson.fromJson(reader, StagingRepositories.class).getData().stream()
                    .filter( r -> r.getType() == Status.closed)
                    .filter( r -> r.getRepositoryId().startsWith(REPOSITORY_PREFIX) )
                    .filter( r -> r.getRepositoryId().endsWith("-" + stagingRepositoryId))
                    .findFirst()
                    .orElseThrow(() -> new IllegalArgumentException("No repository found with id " + stagingRepositoryId));            
        });
    }
    
    private <T> T withStagingRepositories(Function<InputStreamReader, T> function) throws IOException {
        try ( CloseableHttpClient client = httpClientFactory.newClient() ) {
            HttpGet get = new HttpGet("https://repository.apache.org/service/local/staging/profile_repositories");
            get.addHeader("Accept", "application/json");
            try ( CloseableHttpResponse response = client.execute(get)) {
                try ( InputStream content = response.getEntity().getContent();
                        InputStreamReader reader = new InputStreamReader(content)) {
                    if ( response.getStatusLine().getStatusCode() != 200 )
                        throw new IOException("Status line : " + response.getStatusLine());
                    
                    return function.apply(reader);
                }
            }
        }       
    }

    @NotNull
    public LocalRepository download(@NotNull StagingRepository repository) throws IOException {
        readWriteLock.readLock().lock();
        LocalRepository localRepository = repositories.get(repository.getRepositoryId());
        if (localRepository == null) {
            readWriteLock.readLock().unlock();
            readWriteLock.writeLock().lock();
            try {
                if (!repositories.containsKey(repository.getRepositoryId())) {
                    try (CloseableHttpClient client = httpClientFactory.newClient()) {
                        HttpGet get =
                                new HttpGet("https://repository.apache.org/service/local/lucene/search?g=org.apache.sling&repositoryId=" +
                                        repository.getRepositoryId());
                        get.addHeader("Accept", "application/json");
                        try (CloseableHttpResponse response = client.execute(get)) {
                            try (InputStream content = response.getEntity().getContent();
                                 InputStreamReader reader = new InputStreamReader(content)) {
                                JsonParser parser = new JsonParser();
                                JsonObject json = parser.parse(reader).getAsJsonObject();
                                JsonArray data = json.get("data").getAsJsonArray();
                                Set<Artifact> artifacts = new HashSet<>();
                                for (JsonElement dataElement : data) {
                                    JsonObject dataElementJson = dataElement.getAsJsonObject();
                                    String groupId = dataElementJson.get("groupId").getAsString();
                                    String artifactId = dataElementJson.get("artifactId").getAsString();
                                    String version = dataElementJson.get("version").getAsString();
                                    JsonArray artifactLinksArray =
                                            dataElementJson.get("artifactHits").getAsJsonArray().get(0).getAsJsonObject().get("artifactLinks")
                                                    .getAsJsonArray();
                                    for (JsonElement artifactLinkElement : artifactLinksArray) {
                                        JsonObject artifactLinkJson = artifactLinkElement.getAsJsonObject();
                                        String type = artifactLinkJson.get("extension").getAsString();
                                        String classifier = null;
                                        if (artifactLinkJson.has("classifier")) {
                                            classifier = artifactLinkJson.get("classifier").getAsString();
                                        }
                                        artifacts.add(new Artifact(groupId,artifactId, version, classifier, type));
                                    }
                                }
                                Path rootFolder = Files.createTempDirectory(repository.getRepositoryId() + "_");
                                for (Artifact artifact : artifacts) {
                                    String fileRelativePath = artifact.getRepositoryRelativePath();
                                    String relativeFolderPath = fileRelativePath.substring(0, fileRelativePath.lastIndexOf('/'));
                                    Path artifactFolderPath = Files.createDirectories(rootFolder.resolve(relativeFolderPath));
                                    downloadArtifactFile(repository, client, artifactFolderPath, fileRelativePath);
                                    downloadArtifactFile(repository, client, artifactFolderPath,
                                            artifact.getRepositoryRelativeSignaturePath());
                                    downloadArtifactFile(repository, client, artifactFolderPath,
                                            artifact.getRepositoryRelativeSha1SumPath());
                                    downloadArtifactFile(repository, client, artifactFolderPath,
                                            artifact.getRepositoryRelativeMd5SumPath());
                                }
                                localRepository = new LocalRepository(repository, artifacts, rootFolder);
                                repositories.put(localRepository.getRepositoryId(), localRepository);
                            }
                        }
                    }
                }
                readWriteLock.readLock().lock();
            } finally {
                readWriteLock.writeLock().unlock();
            }
        }
        try {
            if (localRepository == null) {
                throw new IOException("Failed to download repository artifacts.");
            }
            return localRepository;
        } finally {
            readWriteLock.readLock().unlock();
        }
    }

    private void downloadArtifactFile(@NotNull StagingRepository repository, CloseableHttpClient client, Path artifactFolderPath,
                                      String relativeFilePath) throws IOException {
        String fileName = relativeFilePath.substring(relativeFilePath.lastIndexOf('/') + 1);
        Path filePath = Files.createFile(artifactFolderPath.resolve(fileName));
        HttpGet get = new HttpGet(repository.getRepositoryURI() + "/" + relativeFilePath);
        LOGGER.debug("Downloading " + get.getURI().toString());
        try (CloseableHttpResponse response = client.execute(get)) {
            try (InputStream content = response.getEntity().getContent()) {
                IOUtils.copyLarge(content, Files.newOutputStream(filePath));
            }
        }
    }
}
