package com.atlassian.bitbucket.internal.branch.model.configuration.rest;

import com.atlassian.bitbucket.internal.branch.model.configuration.BranchModelConfiguration;
import com.atlassian.bitbucket.rest.RestMapEntity;
import com.atlassian.bitbucket.rest.annotation.JsonSurrogate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Map;

@JsonSerialize
@JsonSurrogate(BranchModelConfiguration.class)
public class RestBranchModelConfiguration extends RestMapEntity {

    public static final String USE_DEFAULT = "useDefault"; // only in PUT requests
    public static final String DEVELOPMENT = "development";
    public static final String PRODUCTION = "production";
    public static final String TYPES = "types";

    @SuppressWarnings("unused") //Required for Jersey
    public RestBranchModelConfiguration() {
    }

    public RestBranchModelConfiguration(@Nonnull BranchModelConfiguration configuration) {
        put(DEVELOPMENT, new RestBranchConfiguration(configuration.getDevelopment()));
        if (configuration.getProduction() != null) {
            put(PRODUCTION, new RestBranchConfiguration(configuration.getProduction()));
        }
        put(TYPES, Collections2.transform(configuration.getTypes(), RestBranchTypeConfiguration.REST_TRANSFORM));
    }

    private RestBranchModelConfiguration(Map<String, Object> json) {
        super(json);
    }

    @Nullable
    @SuppressWarnings("unchecked")
    public static RestBranchModelConfiguration valueOf(@Nullable Object value) {
        if (value instanceof RestBranchModelConfiguration) {
            return (RestBranchModelConfiguration) value;
        } else if (value instanceof Map) {
            return new RestBranchModelConfiguration((Map<String, Object>) value);
        }
        return null;
    }

    public boolean isUseDefault() {
        return getBoolProperty(USE_DEFAULT);
    }

    @SuppressWarnings("unchecked")
    public Iterable<RestBranchTypeConfiguration> getTypes() {
        if (get(TYPES) == null) {
            return Collections.emptyList();
        }
        return Iterables.transform((Iterable) get(TYPES), RestBranchTypeConfiguration.REST_TRANSFORM);
    }

    public RestBranchConfiguration getDevelopmentBranch() {
        return RestBranchConfiguration.valueOf(get(DEVELOPMENT));
    }

    public RestBranchConfiguration getProductionBranch() {
        return RestBranchConfiguration.valueOf(get(PRODUCTION));
    }
}
