package com.atlassian.webdriver.bitbucket.element;

import com.atlassian.pageobjects.PageBinder;
import com.atlassian.pageobjects.elements.PageElement;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;

public class UserAndGroupOption extends IdOption {

    @Inject
    protected PageBinder pageBinder;

    public UserAndGroupOption(PageElement container) {
        super(container);
    }

    /**
     * Matches any option, either user or group, by name.
     * @param id expected ID of the option (either username or group name)
     * @return ID matching predicate
     * @see UserOption
     * @see GroupOption
     */
    @Nonnull
    public static Predicate<UserAndGroupOption> idMatches(@Nonnull final String id) {
        return IdOption.idMatches(UserAndGroupOption.class, id);
    }

    @Nullable
    public String getDisplayName() {
        if (!isUserOption()) {
            return null;
        }

        return getUserOption().getDisplayName();
    }

    @Nullable
    public String getGroupName() {
        if (!isGroupOption()) {
            return null;
        }

        return getGroupOption().getGroupName();
    }

    @Nullable
    public String getId() {
        if (isGroupOption()) {
            return getGroupName();
        } else if (isUserOption()) {
            return getUsername();
        }

        throw new AssertionError("Unrecognized option: " + this);
    }

    @Nullable
    public String getUsername() {
        if (!isUserOption()) {
            return null;
        }

        return getUserOption().getUsername();
    }

    public boolean isGroupOption() {
        return getGroupOption().getGroupContainer().isPresent();
    }

    public boolean isUserOption() {
        return getUserOption().getUsernameContainer().isPresent();
    }

    @Nonnull
    protected GroupOption getGroupOption() {
        return pageBinder.bind(GroupOption.class, container);
    }

    @Nonnull
    protected UserOption getUserOption() {
        return pageBinder.bind(UserOption.class, container);
    }

    @Override
    protected void extendToString(Objects.ToStringHelper toStringHelper) {
        toStringHelper.add("id", getId());
    }
}
