/*
 * 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.geronimo.arthur.impl.nativeimage.installer;

import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import static java.util.Comparator.comparing;
import static java.util.Objects.requireNonNull;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

import org.apache.geronimo.arthur.impl.nativeimage.process.ProcessExecutor;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequiredArgsConstructor
public class SdkmanGraalVMInstaller {
    private final SdkmanGraalVMInstallerConfiguration configuration;

    private Path home;

    public Path install() {
        Path archive;
        try {
            archive = configuration.getResolver().apply(configuration.getGav());
        } catch (final IllegalStateException ise) {
            if (configuration.isOffline()) {
                throw new IllegalStateException("GraalVM was not found and mvn runs offline");
            }
            try {
                if (!Files.exists(configuration.getWorkdir())) {
                    Files.createDirectories(configuration.getWorkdir());
                }

                log.info("Downloading GraalVM {}, this can be long", configuration.getVersion());
                final Path download = download();

                log.info("Installing GraalVM {}", configuration.getGav());
                archive = configuration.getInstaller().apply(configuration.getGav(), download);
            } catch (final IOException e) {
                throw new IllegalStateException("Can't cache graal locally", e);
            }
        }
        if (!Files.exists(archive)) {
            throw new IllegalStateException("No graal archive available: " + archive);
        }

        final Path exploded = archive.getParent().resolve("distribution_exploded");
        if (!Files.isDirectory(exploded)) {
            configuration.getExtractor().accept(archive, exploded);
        }
        return home = exploded;
    }

    public Path installNativeImage() {
        final Path bin = requireNonNull(this.home, "No home, ensure to call install() before installNativeImage()")
                .resolve("bin");
        try {
            if (findNativeImage(bin).count() == 0) { // likely only UNIx, windows comes with native-image.cmd
                log.info("Installing native-image");
                new ProcessExecutor(
                        configuration.isInheritIO(), asList(findGu(bin).toAbsolutePath().toString(), "install", "native-image"),
                        singletonMap("GRAALVM_HOME", home.toString())).run();
            } else {
                log.debug("native-image is already available");
            }
            return findNativeImage(bin)
                    .min(comparing(p -> p.getFileName().toString().length())) // support windows this way (.cmd)
                    .orElseThrow(() -> new IllegalArgumentException("No native-image found in " + bin));
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        }
    }

    private Stream<Path> findNativeImage(final Path bin) throws IOException {
        return Files.list(bin).filter(path -> path.getFileName().toString().startsWith("native-image"));
    }

    private Path findGu(final Path bin) {
        try {
            return Files.list(bin)
                    .filter(path -> path.getFileName().toString().startsWith("gu"))
                    .min(comparing(p -> p.getFileName().toString().length()))
                    .orElseThrow(() -> new IllegalStateException("No gu found in " + bin));
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        }
    }

    private Path download() throws IOException {
        final String fname = "graal-" + configuration.getVersion() + "-" + configuration.getPlatform() + "." + configuration.getGav().split(":")[2];
        final Path cache = configuration.getWorkdir().resolve(fname);
        if (Files.exists(cache)) {
            return cache;
        }

        final URL source = new URL(configuration.getUrl());
        final HttpURLConnection connection = HttpURLConnection.class.cast(source.openConnection());
        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(true); // sdkman broker redirects on github
        try (final InputStream stream = new BufferedInputStream(connection.getInputStream())) {
            Files.copy(stream, cache);
        } catch (final IOException ioe) {
            if (Files.exists(cache)) {
                Files.delete(cache);
            }
            throw ioe;
        }
        return cache;
    }
}
