package com.atlassian.bitbucket.internal.mirroring.rest.auth;

import com.atlassian.bitbucket.internal.mirroring.ssh.encoding.DefaultPublicKeyEncodingHelper;
import com.atlassian.bitbucket.rest.RestMapEntity;
import com.atlassian.bitbucket.validation.annotation.RequiredString;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import javax.annotation.Nullable;
import java.security.PublicKey;
import java.util.Map;

@JsonSerialize
public class RestPublicKey extends RestMapEntity {
    private static final String KEY_TEXT = "keyText";
    private static final String ALGORITHM = "algorithm";

    // default ctor for jersey
    @SuppressWarnings("unused")
    public RestPublicKey() {
    }

    public RestPublicKey(String keyText, String algorithm) {
        putIfNotNull(KEY_TEXT, keyText);
        putIfNotNull(ALGORITHM, algorithm);
    }

    private RestPublicKey(Map<String, Object> map) {
        super(map);
    }

    @RequiredString(message = "{bitbucket.mirroring.authentication.ssh.publickey.keytext.required}", size = Integer.MAX_VALUE)
    public String getKeyText() {
        return getStringProperty(KEY_TEXT);
    }

    @RequiredString(message = "{bitbucket.mirroring.authentication.ssh.publickey.algorithm.required}")
    public String getAlgorithm() {
        return getStringProperty(ALGORITHM);
    }

    public PublicKey toPublicKey() {
        return new DefaultPublicKeyEncodingHelper().decodeBytesFromBase64(getKeyText(), getAlgorithm());
    }

    @SuppressWarnings("unused")
    public static final RestPublicKey EXAMPLE_PUBLIC_KEY = new RestPublicKey("MMI435...", "RSA");

    @Nullable
    @SuppressWarnings("unchecked")
    public static RestPublicKey valueOf(@Nullable Object value) {
        if (value instanceof RestPublicKey) {
            return (RestPublicKey) value;
        } else if (value instanceof Map) {
            return new RestPublicKey((Map) value);
        }
        return null;
    }

    public static final RestPublicKey EXAMPLE = new RestPublicKey("MMI435...", "RSA");
}
