package be.iminds.ilabt.jfed.lowlevel.api.user_spec;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;

/**
 * UserSpec used in Aggregate Manager V2 and V3
 */
public class UserSpec {
    @Nullable
    protected final String urn;
    @Nonnull
    protected final List<String> sshKey;

    /**
     * @param sshKeys a list of ssh keys for the user. Note: an internal copy is taken by this constructor.
     */
    public UserSpec(@Nonnull String urn, @Nullable Collection<String> sshKeys) {
        this.urn = urn;
        if (sshKeys != null)
            this.sshKey = new ArrayList<>(sshKeys);
        else
            this.sshKey = Collections.emptyList();
    }

    public UserSpec(@Nonnull String urn, @Nullable String sshKey) {
        this.urn = urn;
        this.sshKey = new ArrayList<>();
        if (sshKey != null)
            this.sshKey.add(sshKey);
    }

    public UserSpec(UserSpec orig) {
        this.urn = orig.urn;
        this.sshKey = new ArrayList<>(orig.sshKey);
    }

    public UserSpec(String urn) {
        this(urn, new ArrayList<>());
    }

    /**
     * urn may be null, if used in http://jfed.iminds.be/rspec/ext/jfed-ssh-keys/1 rspec extension,
     * but NOT when used as part of AMv2 CreateSliver or AMv3 Provision command.
     */
    @Nullable
    public String getUrn() {
        return urn;
    }

    @Nonnull
    public List<String> getSshKey() {
        return sshKey;
    }

    @Override
    public String toString() {
        return "UserSpec{" +
                "urn='" + urn + '\'' +
                ", sshKey=" + sshKey +
                '}';
    }

    public Map getAsMap() {
        Map<String, Object> res = new HashMap<>();
        //urn must be non null when used as part of AMv2 CreateSliver or AMv3 Provision command.
        assert urn != null;
        res.put("urn", urn);
        res.put("keys", sshKey);
        return res;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        UserSpec userSpec = (UserSpec) o;

        if (!Objects.equals(sshKey, userSpec.sshKey)) return false;
        if (urn != null ? !Objects.equals(urn, userSpec.urn) : userSpec.urn != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = urn != null ? urn.hashCode() : 0;
        result = 31 * result + sshKey.hashCode();
        return result;
    }
}
