package io.kaif.model.zone;
import static java.util.Arrays.asList;
import java.time.Instant;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import io.kaif.model.account.Account;
import io.kaif.model.account.Authority;
import io.kaif.model.account.Authorization;
import io.kaif.web.v1.dto.V1ZoneDto;
/**
* Although authorities has lots of combination, but valid cases are:
* <p>
* 1) default -- CITIZEN allow: upVote, write, debate
* <p>
* 2) kaif -- CITIZEN allow: upVote, debate, zoneAdmin allow write
* <p>
* 3) kVoting -- CITIZEN allow: debate, SUFFRAGE allow upVote, zoneAdmins allow write
* <p>
* 4) vote -- CITIZEN allow: upVote, debate, zoneAdmins allow write
* <p>
* CITIZEN allow up/down vote on PEOPLE, regardless ZoneInfo settings
*/
public class ZoneInfo {
public static final int ALIAS_NAME_MAX = 20;
public static final String THEME_DEFAULT = "z-theme-default";
// theme used in site related zone, like Blog or FAQ
public static final String THEME_KAIF = "z-theme-kaif";
public static final String THEME_NORMAL_VOTING = "z-theme-normal-voting";
public static final String THEME_K_VOTING = "z-theme-k-voting";
public static final String RESERVED_WORD = "kaif";
public static ZoneInfo createKVoting(String zoneValue,
String aliasName,
Account creator,
Instant now) {
checkDefault(zoneValue);
checkAliasName(aliasName);
boolean hideFromTopRanking = false;
Authority voteAuth = Authority.SUFFRAGE;
Authority debateAuth = Authority.CITIZEN;
Authority writeAuth = Authority.FORBIDDEN;
return new ZoneInfo(Zone.valueOf(zoneValue),
aliasName,
THEME_K_VOTING,
voteAuth,
debateAuth,
writeAuth,
asList(creator.getAccountId()),
hideFromTopRanking,
now);
}
public static ZoneInfo createNormalVoting(String zoneValue,
String aliasName,
Account creator,
Instant now) {
checkDefault(zoneValue);
checkAliasName(aliasName);
boolean hideFromTopRanking = false;
Authority voteAuth = Authority.CITIZEN;
Authority debateAuth = Authority.CITIZEN;
Authority writeAuth = Authority.FORBIDDEN;
return new ZoneInfo(Zone.valueOf(zoneValue),
aliasName,
THEME_NORMAL_VOTING,
voteAuth,
debateAuth,
writeAuth,
asList(creator.getAccountId()),
hideFromTopRanking,
now);
}
/**
* zone allow tourist to vote/debate/write ...etc, this should be test zone
*/
public static ZoneInfo createTourist(String zoneValue, String aliasName, Instant now) {
checkAliasName(aliasName);
boolean hideFromTopRanking = true;
Authority voteAuth = Authority.TOURIST;
Authority debateAuth = Authority.TOURIST;
Authority writeAuth = Authority.TOURIST;
return new ZoneInfo(Zone.valueOf(zoneValue),
aliasName,
THEME_DEFAULT,
voteAuth,
debateAuth,
writeAuth,
Collections.emptyList(),
hideFromTopRanking,
now);
}
public static ZoneInfo createKaif(String zoneValue, String aliasName, Instant now) {
checkAliasName(aliasName);
boolean hideFromTopRanking = true;
Authority voteAuth = Authority.CITIZEN;
Authority debateAuth = Authority.CITIZEN;
Authority writeAuth = Authority.FORBIDDEN;
return new ZoneInfo(Zone.valueOf(zoneValue),
aliasName,
THEME_KAIF,
voteAuth,
debateAuth,
writeAuth,
Collections.emptyList(),
hideFromTopRanking,
now);
}
public static ZoneInfo createDefault(String zoneValue, String aliasName, Instant now) {
checkDefault(zoneValue);
checkAliasName(aliasName);
boolean hideFromTopRanking = false;
Authority voteAuth = Authority.CITIZEN;
Authority debateAuth = Authority.CITIZEN;
Authority writeAuth = Authority.CITIZEN;
return new ZoneInfo(Zone.valueOf(zoneValue),
aliasName,
THEME_DEFAULT,
voteAuth,
debateAuth,
writeAuth,
Collections.emptyList(),
hideFromTopRanking,
now);
}
private static void checkAliasName(String aliasName) {
Preconditions.checkArgument(aliasName.length() <= ALIAS_NAME_MAX);
}
private static void checkDefault(String zoneValue) {
Preconditions.checkArgument(isValidDefault(zoneValue));
}
public static boolean isValidDefault(String zoneValue) {
return !zoneValue.contains(RESERVED_WORD);
}
/**
* zone are always lowercase and URL friendly
*/
private final Zone zone;
/**
* display name of zone, may include Upper case or even Chinese
*/
private final String aliasName;
/**
* css theme class name
*/
private final String theme;
/**
* which authority can vote on this zone
*/
private final Authority voteAuthority;
/**
* which authority can debate on this zone
*/
private final Authority debateAuthority;
/**
* which authority can write article in this zone
*/
private final Authority writeAuthority;
/**
* accountId can do everything about this zone, he ignore all authority check
*/
private final List<UUID> adminAccountIds;
/**
* hide this zone in home page top ranking
*/
private final boolean hideFromTop;
private final Instant createTime;
ZoneInfo(Zone zone,
String aliasName,
String theme,
Authority voteAuthority,
Authority debateAuthority,
Authority writeAuthority,
List<UUID> adminAccountIds,
boolean hideFromTop,
Instant createTime) {
this.zone = zone;
this.aliasName = aliasName;
this.theme = theme;
this.voteAuthority = voteAuthority;
this.debateAuthority = debateAuthority;
this.writeAuthority = writeAuthority;
this.adminAccountIds = adminAccountIds;
this.hideFromTop = hideFromTop;
this.createTime = createTime;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ZoneInfo zoneInfo = (ZoneInfo) o;
if (zone != null ? !zone.equals(zoneInfo.zone) : zoneInfo.zone != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
return zone != null ? zone.hashCode() : 0;
}
public Zone getZone() {
return zone;
}
public String getAliasName() {
return aliasName;
}
public Authority getVoteAuthority() {
return voteAuthority;
}
public String getTheme() {
return theme;
}
public Authority getWriteAuthority() {
return writeAuthority;
}
public List<UUID> getAdminAccountIds() {
return adminAccountIds;
}
public Instant getCreateTime() {
return createTime;
}
public Authority getDebateAuthority() {
return debateAuthority;
}
public boolean canUpVote(Authorization auth) {
if (auth.belongToAccounts(adminAccountIds)) {
return true;
}
return auth.containsAuthority(voteAuthority);
}
public boolean canDebate(Authorization auth) {
if (auth.belongToAccounts(adminAccountIds)) {
return true;
}
return auth.containsAuthority(debateAuthority);
}
public boolean canWriteArticle(Authorization auth) {
if (auth.belongToAccounts(adminAccountIds)) {
return true;
}
return auth.containsAuthority(writeAuthority);
}
public boolean canContributeVoteStats() {
return voteAuthority == Authority.CITIZEN;
}
public boolean isHideFromTop() {
return hideFromTop;
}
public ZoneInfo withAdmins(List<UUID> accountIds) {
return new ZoneInfo(zone,
aliasName,
theme,
voteAuthority,
debateAuthority,
writeAuthority,
ImmutableList.copyOf(accountIds),
hideFromTop,
createTime);
}
/**
* shortcut to zone.value()
*/
public String getName() {
return zone.value();
}
@Override
public String toString() {
return "/z/" + zone;
}
public V1ZoneDto toV1Dto() {
return new V1ZoneDto(getName(), getAliasName());
}
}