package com.atlassian.bitbucket.test;

import com.atlassian.fugue.Option;
import com.google.common.base.Supplier;

import javax.annotation.Nonnull;

public class BitbucketTestLicense {
    private final Option<String> clusteredLicense;
    private final Option<String> standaloneLicense;

    private BitbucketTestLicense(Option<String> clusteredLicense, Option<String> nonClusteredLicense) {
        this.clusteredLicense = clusteredLicense;
        this.standaloneLicense = nonClusteredLicense;
    }

    public String get() {
        return ProductTopology.get().accept(new ProductTopologyAdapter<String>() {
            @Override
            public String visitDefault() {
                return getNonClusteredVersion();
            }

            @Override
            public String visitStashClusterPair() {
                return getClusteredVersion();
            }
        });
    }

    public String getClusteredVersion() {
        return clusteredLicense.getOrThrow(new Supplier<IllegalStateException>() {
            @Override
            public IllegalStateException get() {
                return new IllegalStateException("A clustered license is required for this operation but one has not been supplied");
            }
        });
    }

    public String getNonClusteredVersion() {
        return standaloneLicense.getOrThrow(new Supplier<IllegalStateException>() {
            @Override
            public IllegalStateException get() {
                return new IllegalStateException("A standalone license is required for this operation but one has not been supplied");
            }
        });
    }

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

    public static class Builder {
        private Option<String> clusteredLicense;
        private Option<String> standaloneLicense;

        public Builder whenClustered(@Nonnull String license) {
            clusteredLicense = Option.some(license);
            return this;
        }

        public Builder whenNonClustered(@Nonnull String license) {
            standaloneLicense = Option.some(license);
            return this;
        }

        public BitbucketTestLicense build() {
            return new BitbucketTestLicense(clusteredLicense, standaloneLicense);
        }
    }
}
