/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Copyright 2020-2021 The JReleaser authors.
 *
 * Licensed 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
 *
 *     https://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.jreleaser.sdk.sdkman;

import org.jreleaser.util.JReleaserLogger;

import java.util.LinkedHashMap;
import java.util.Map;

import static org.jreleaser.util.StringUtils.isBlank;
import static org.jreleaser.util.StringUtils.isNotBlank;
import static org.jreleaser.util.StringUtils.requireNonBlank;

/**
 * @author Andres Almiray
 * @since 0.1.0
 */
public class MinorReleaseSdkmanCommand extends AbstractSdkmanCommand {
    private final boolean skipAnnounce;
    private final String hashtag;
    private final String releaseNotesUrl;
    private final Map<String, String> platforms = new LinkedHashMap<>();

    private MinorReleaseSdkmanCommand(JReleaserLogger logger,
                                      String apiHost,
                                      int connectTimeout,
                                      int readTimeout,
                                      String consumerKey,
                                      String consumerToken,
                                      String candidate,
                                      String version,
                                      boolean dryrun,
                                      boolean skipAnnounce,
                                      String hashtag,
                                      String releaseNotesUrl,
                                      Map<String, String> platforms) {
        super(logger, apiHost, connectTimeout, readTimeout, consumerKey, consumerToken, candidate, version, dryrun);
        this.skipAnnounce = skipAnnounce;
        this.hashtag = hashtag;
        this.releaseNotesUrl = releaseNotesUrl;
        this.platforms.putAll(platforms);
    }

    @Override
    public void execute() throws SdkmanException {
        sdkman.minorRelease(candidate, version, platforms, hashtag, releaseNotesUrl, skipAnnounce);
    }

    public static Builder builder(JReleaserLogger logger) {
        return new Builder(logger);
    }

    public static class Builder extends AbstractSdkmanCommand.Builder<Builder> {
        private final Map<String, String> platforms = new LinkedHashMap<>();
        private String hashtag;
        private String releaseNotesUrl;
        private String url;

        protected Builder(JReleaserLogger logger) {
            super(logger);
        }

        /**
         * The hashtag to use (legacy)
         */
        public Builder hashtag(String hashtag) {
            this.hashtag = hashtag;
            return this;
        }

        /**
         * The URL where the release notes can be found
         */
        public Builder releaseNotesUrl(String releaseNotesUrl) {
            this.releaseNotesUrl = releaseNotesUrl;
            return this;
        }

        /**
         * The URL from where the candidate version can be downloaded
         */
        public Builder url(String url) {
            this.url = url;
            return this;
        }

        /**
         * Platform to downloadable URL mappings.
         * Supported platforms are:
         * <ul>
         * <li>MAC_OSX</li>
         * <li>WINDOWS_64</li>
         * <li>LINUX_64</li>
         * <li>LINUX_32</li>
         * </ul>
         * Example:
         * <pre>
         *     "MAC_OSX"   :"https://host/micronaut-x.y.z-macosx.zip"
         *     "LINUX_64"  :"https://host/micronaut-x.y.z-linux64.zip"
         *     "WINDOWS_64":"https://host/micronaut-x.y.z-win.zip"
         * </pre>
         */
        public Builder platforms(Map<String, String> platforms) {
            this.platforms.putAll(platforms);
            return this;
        }

        public Builder platform(String platform, String url) {
            this.platforms.put(
                requireNonBlank(platform, "'platform' must not be blank").trim(),
                requireNonBlank(url, "'url' must not be blank").trim());
            return this;
        }

        public MinorReleaseSdkmanCommand build() {
            requireNonBlank(apiHost, "'apiHost' must not be blank");
            requireNonBlank(consumerKey, "'consumerKey' must not be blank");
            requireNonBlank(consumerToken, "'consumerToken' must not be blank");
            requireNonBlank(candidate, "'candidate' must not be blank");
            requireNonBlank(version, "'version' must not be blank");

            // url is required if platforms is empty
            if ((platforms.isEmpty()) && isBlank(url)) {
                throw new IllegalArgumentException("Missing url");
            }
            if (isNotBlank(url)) {
                platforms.put("UNIVERSAL", url);
            }

            return new MinorReleaseSdkmanCommand(
                logger,
                apiHost,
                connectTimeout,
                readTimeout,
                consumerKey,
                consumerToken,
                candidate,
                version,
                dryrun,
                skipAnnounce,
                hashtag,
                releaseNotesUrl,
                platforms);
        }
    }
}
