// VENDORED COPY - do not edit here.
// Source of truth: apache/camel
//   dsl/camel-jbang/camel-launcher/src/jreleaser/java/WebsiteManifestGenerator.java
// To update: re-copy that file over this one, then re-apply this banner. The body below is
// kept byte-identical to the upstream source so the sync stays a mechanical copy.

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

// Intentionally in the default package so camel-package.sh can run this JDK-only source-file
// tool directly by path without compiling or loading a package-qualified launcher class.

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HexFormat;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * JDK-only tool that computes SHA-256 checksums for a release TAR/ZIP pair and writes the
 * website's four-field release manifest ({@code format}, {@code version}, {@code tar_sha256},
 * {@code zip_sha256}). Per-version manifests are immutable; {@code latest.properties} can only
 * move forward to a higher semantic version and cannot silently change checksums for the same
 * version. Writes are atomic.
 *
 * <p>
 * Usage: {@code java WebsiteManifestGenerator.java --version X.Y.Z --tar <path> --zip <path>
 * --output <dir> --latest <true|false>}
 */
public class WebsiteManifestGenerator {

    private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)$");
    private static final Set<String> REQUIRED_OPTIONS
            = new LinkedHashSet<>(List.of("--version", "--tar", "--zip", "--output", "--latest"));
    private static final Set<String> OPTIONAL_OPTIONS = Set.of("--install-sh", "--install-ps1");
    private static final Set<String> MANIFEST_KEYS
            = new LinkedHashSet<>(List.of("format", "version", "tar_sha256", "zip_sha256"));
    private static final String MANIFEST_FORMAT = "1";

    // Properties-style ASF license header prepended to every generated manifest. These '#' comment
    // lines carry no data and are skipped by this tool's own strict re-parser (parseStrictManifest)
    // and by the installers (install.sh / install.ps1), which tolerate a commented manifest.
    private static final String LICENSE_HEADER
            = "## ---------------------------------------------------------------------------\n"
              + "## Licensed to the Apache Software Foundation (ASF) under one or more\n"
              + "## contributor license agreements.  See the NOTICE file distributed with\n"
              + "## this work for additional information regarding copyright ownership.\n"
              + "## The ASF licenses this file to You under the Apache License, Version 2.0\n"
              + "## (the \"License\"); you may not use this file except in compliance with\n"
              + "## the License.  You may obtain a copy of the License at\n"
              + "##\n"
              + "##      http://www.apache.org/licenses/LICENSE-2.0\n"
              + "##\n"
              + "## Unless required by applicable law or agreed to in writing, software\n"
              + "## distributed under the License is distributed on an \"AS IS\" BASIS,\n"
              + "## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
              + "## See the License for the specific language governing permissions and\n"
              + "## limitations under the License.\n"
              + "## ---------------------------------------------------------------------------\n";

    public static void main(String[] args) {
        try {
            run(args);
        } catch (UsageException e) {
            System.err.println("Error: " + e.getMessage());
            System.exit(2);
        } catch (ConflictException | IOException e) {
            System.err.println("Error: " + e.getMessage());
            System.exit(1);
        }
    }

    private static void run(String[] args) throws IOException {
        Map<String, String> options = parseArgs(args);

        String version = options.get("--version");
        if (!VERSION_PATTERN.matcher(version).matches()) {
            throw new UsageException("'" + version + "' is not a valid release version (expected X.Y.Z).");
        }

        Path tar = Paths.get(options.get("--tar"));
        Path zip = Paths.get(options.get("--zip"));
        if (!Files.isRegularFile(tar)) {
            throw new UsageException("TAR artifact not found: " + tar);
        }
        if (!Files.isRegularFile(zip)) {
            throw new UsageException("ZIP artifact not found: " + zip);
        }

        Path installSh = null;
        Path installPs1 = null;
        String installShValue = options.get("--install-sh");
        if (installShValue != null) {
            installSh = Paths.get(installShValue);
            if (!Files.isRegularFile(installSh)) {
                throw new UsageException("install.sh not found: " + installSh);
            }
        }
        String installPs1Value = options.get("--install-ps1");
        if (installPs1Value != null) {
            installPs1 = Paths.get(installPs1Value);
            if (!Files.isRegularFile(installPs1)) {
                throw new UsageException("install.ps1 not found: " + installPs1);
            }
        }

        String latestValue = options.get("--latest");
        boolean latest;
        if ("true".equals(latestValue)) {
            latest = true;
        } else if ("false".equals(latestValue)) {
            latest = false;
        } else {
            throw new UsageException("--latest must be 'true' or 'false' (got '" + latestValue + "').");
        }

        Path output = Paths.get(options.get("--output"));

        String tarSha256 = sha256Hex(tar);
        String zipSha256 = sha256Hex(zip);
        byte[] manifest = renderManifest(version, tarSha256, zipSha256);

        Path releasesDir = output.resolve("releases");
        Files.createDirectories(releasesDir);
        writeVersionManifest(releasesDir.resolve(version + ".properties"), manifest, version);

        if (latest) {
            writeLatestManifest(releasesDir.resolve("latest.properties"), manifest, version);
        }

        if (installSh != null && installPs1 != null) {
            writeInstallChecksums(output.getParent(), installSh, installPs1);
        }
    }

    private static Map<String, String> parseArgs(String[] args) {
        Map<String, String> options = new LinkedHashMap<>();
        int i = 0;
        while (i < args.length) {
            String key = args[i];
            if (!REQUIRED_OPTIONS.contains(key) && !OPTIONAL_OPTIONS.contains(key)) {
                throw new UsageException("unknown option '" + key + "'.");
            }
            if (i + 1 >= args.length) {
                throw new UsageException("option '" + key + "' requires a value.");
            }
            if (options.containsKey(key)) {
                throw new UsageException("option '" + key + "' was specified more than once.");
            }
            options.put(key, args[i + 1]);
            i += 2;
        }
        for (String required : REQUIRED_OPTIONS) {
            if (!options.containsKey(required)) {
                throw new UsageException("missing required option '" + required + "'.");
            }
        }
        return options;
    }

    private static byte[] renderManifest(String version, String tarSha256, String zipSha256) {
        String content = LICENSE_HEADER
                          + "format=" + MANIFEST_FORMAT + "\n"
                          + "version=" + version + "\n"
                          + "tar_sha256=" + tarSha256 + "\n"
                          + "zip_sha256=" + zipSha256 + "\n";
        return content.getBytes(StandardCharsets.UTF_8);
    }

    private static void writeVersionManifest(Path versionFile, byte[] manifest, String version) throws IOException {
        if (Files.exists(versionFile)) {
            byte[] existing = Files.readAllBytes(versionFile);
            if (Arrays.equals(existing, manifest)) {
                return;
            }
            throw new ConflictException("version manifest for " + version + " already exists with different content"
                                         + " (" + versionFile + ") - version manifests are immutable.");
        }
        atomicWrite(versionFile, manifest);
    }

    private static void writeLatestManifest(Path latestFile, byte[] manifest, String version) throws IOException {
        if (!Files.exists(latestFile)) {
            atomicWrite(latestFile, manifest);
            return;
        }

        byte[] existing = Files.readAllBytes(latestFile);
        if (Arrays.equals(existing, manifest)) {
            return;
        }

        Map<String, String> existingFields = parseStrictManifest(existing, latestFile);
        String existingVersion = existingFields.get("version");
        int cmp = compareSemver(version, existingVersion);
        if (cmp < 0) {
            throw new ConflictException(
                    "latest.properties already points at a newer version (" + existingVersion + "); refusing to"
                                         + " move backward to " + version + ".");
        } else if (cmp == 0) {
            throw new ConflictException("latest.properties already has different checksums for version " + version
                                         + " - refusing to overwrite.");
        }
        atomicWrite(latestFile, manifest);
    }

    // install.sh/install.ps1 aren't versioned the way the release archive is - they always describe
    // "how to install whatever is currently latest," so unlike writeVersionManifest/writeLatestManifest
    // there's no immutability or monotonic-version invariant to enforce here: this file is simply
    // overwritten every release with the checksums of whatever install.sh/install.ps1 currently are.
    private static void writeInstallChecksums(Path websiteRoot, Path installSh, Path installPs1) throws IOException {
        String content = "install_sh_sha256=" + sha256Hex(installSh) + "\n"
                           + "install_ps1_sha256=" + sha256Hex(installPs1) + "\n";
        atomicWrite(websiteRoot.resolve("install.sha256"), content.getBytes(StandardCharsets.UTF_8));
    }

    private static Map<String, String> parseStrictManifest(byte[] bytes, Path source) {
        String content = new String(bytes, StandardCharsets.UTF_8);
        Map<String, String> fields = new LinkedHashMap<>();
        for (String line : content.split("\n", -1)) {
            // Skip blank lines and '#' comment lines (e.g. the ASF license header this tool now
            // prepends), so re-reading a previously generated latest.properties stays valid.
            if (line.isEmpty() || line.startsWith("#")) {
                continue;
            }
            int eq = line.indexOf('=');
            if (eq < 0) {
                throw new ConflictException("malformed manifest line in " + source + ": '" + line + "'.");
            }
            String key = line.substring(0, eq);
            if (fields.containsKey(key)) {
                throw new ConflictException("malformed manifest in " + source + ": duplicate key '" + key + "'.");
            }
            fields.put(key, line.substring(eq + 1));
        }
        if (!fields.keySet().equals(MANIFEST_KEYS)) {
            throw new ConflictException("malformed manifest in " + source + ": expected keys " + MANIFEST_KEYS
                                         + " but found " + fields.keySet() + ".");
        }
        if (!MANIFEST_FORMAT.equals(fields.get("format"))) {
            throw new ConflictException("malformed manifest in " + source + ": unsupported format '"
                                         + fields.get("format") + "'.");
        }
        if (!VERSION_PATTERN.matcher(fields.get("version")).matches()) {
            throw new ConflictException("malformed manifest in " + source + ": invalid version '"
                                         + fields.get("version") + "'.");
        }
        assertSha256(fields.get("tar_sha256"), source, "tar_sha256");
        assertSha256(fields.get("zip_sha256"), source, "zip_sha256");
        return fields;
    }

    private static void assertSha256(String value, Path source, String key) {
        if (!value.matches("[0-9a-f]{64}")) {
            throw new ConflictException("malformed manifest in " + source + ": invalid " + key + " '" + value + "'.");
        }
    }

    private static int compareSemver(String a, String b) {
        int[] pa = semverParts(a);
        int[] pb = semverParts(b);
        for (int i = 0; i < 3; i++) {
            int c = Integer.compare(pa[i], pb[i]);
            if (c != 0) {
                return c;
            }
        }
        return 0;
    }

    private static int[] semverParts(String version) {
        Matcher m = VERSION_PATTERN.matcher(version);
        if (!m.matches()) {
            throw new ConflictException("invalid semantic version '" + version + "'.");
        }
        return new int[] { Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3)) };
    }

    private static void atomicWrite(Path target, byte[] bytes) throws IOException {
        Path dir = target.toAbsolutePath().getParent();
        Path tmp = Files.createTempFile(dir, "wmg-", ".tmp");
        try {
            Files.write(tmp, bytes);
            try {
                Files.move(tmp, target, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
            } catch (AtomicMoveNotSupportedException e) {
                Files.move(tmp, target, StandardCopyOption.REPLACE_EXISTING);
            }
        } finally {
            Files.deleteIfExists(tmp);
        }
    }

    private static String sha256Hex(Path file) throws IOException {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("SHA-256 is required by the JDK and must always be available.", e);
        }
        try (InputStream in = Files.newInputStream(file)) {
            byte[] buffer = new byte[8192];
            int read;
            while ((read = in.read(buffer)) != -1) {
                digest.update(buffer, 0, read);
            }
        }
        return HexFormat.of().formatHex(digest.digest());
    }

    private static final class UsageException extends RuntimeException {
        UsageException(String message) {
            super(message);
        }
    }

    private static final class ConflictException extends RuntimeException {
        ConflictException(String message) {
            super(message);
        }
    }
}
