package cc.blynk.server.application.handlers.main.logic.dashboard;
import cc.blynk.server.application.handlers.main.auth.AppStateHolder;
import cc.blynk.server.core.dao.TokenManager;
import cc.blynk.server.core.model.DashBoard;
import cc.blynk.server.core.model.auth.User;
import cc.blynk.server.core.model.device.Device;
import cc.blynk.server.core.protocol.exceptions.IllegalCommandException;
import cc.blynk.server.core.protocol.exceptions.NotAllowedException;
import cc.blynk.server.core.protocol.exceptions.QuotaLimitException;
import cc.blynk.server.core.protocol.model.messages.StringMessage;
import cc.blynk.server.workers.timer.TimerWorker;
import cc.blynk.utils.ArrayUtil;
import cc.blynk.utils.JsonParser;
import cc.blynk.utils.StringUtils;
import cc.blynk.utils.TokenGeneratorUtil;
import io.netty.channel.ChannelHandlerContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import static cc.blynk.utils.BlynkByteBufUtil.ok;
/**
* The Blynk Project.
* Created by Dmitriy Dumanskiy.
* Created on 2/1/2015.
*
*/
public class CreateDashLogic {
private static final Logger log = LogManager.getLogger(CreateDashLogic.class);
private final int DASH_MAX_LIMIT;
private final int DASH_MAX_SIZE;
private final TimerWorker timerWorker;
private final TokenManager tokenManager;
public CreateDashLogic(TimerWorker timerWorker, TokenManager tokenManager, int dashMaxLimit, int dashMaxSize) {
this.tokenManager = tokenManager;
this.DASH_MAX_LIMIT = dashMaxLimit;
this.DASH_MAX_SIZE = dashMaxSize;
this.timerWorker = timerWorker;
}
public void messageReceived(ChannelHandlerContext ctx, AppStateHolder state, StringMessage message) {
boolean generateTokensForDevices = true;
final String dashString;
if (message.body.startsWith("no_token")) {
generateTokensForDevices = false;
dashString = StringUtils.split2(message.body)[1];
} else {
dashString = message.body;
}
if (dashString == null || dashString.isEmpty()) {
throw new IllegalCommandException("Income create dash message is empty.");
}
if (dashString.length() > DASH_MAX_SIZE) {
throw new NotAllowedException("User dashboard is larger then limit.");
}
log.debug("Trying to parse user newDash : {}", dashString);
DashBoard newDash = JsonParser.parseDashboard(dashString);
log.info("Creating new dashboard.");
final User user = state.user;
if (user.profile.dashBoards.length >= DASH_MAX_LIMIT) {
throw new QuotaLimitException("Dashboards limit reached.");
}
for (DashBoard dashBoard : user.profile.dashBoards) {
if (dashBoard.id == newDash.id) {
throw new NotAllowedException("Dashboard already exists.");
}
}
if (newDash.createdAt == 0) {
newDash.createdAt = System.currentTimeMillis();
}
user.subtractEnergy(newDash.energySum());
user.profile.dashBoards = ArrayUtil.add(user.profile.dashBoards, newDash, DashBoard.class);
if (newDash.devices == null) {
newDash.devices = ArrayUtil.EMPTY_DEVICES;
} else {
for (Device device : newDash.devices) {
//this case only possible for clone,
device.erase();
if (generateTokensForDevices) {
String token = TokenGeneratorUtil.generateNewToken();
tokenManager.assignToken(user, newDash.id, device.id, token);
}
}
}
user.lastModifiedTs = System.currentTimeMillis();
newDash.addTimers(timerWorker, state.userKey);
if (!generateTokensForDevices) {
newDash.eraseValues();
}
ctx.writeAndFlush(ok(message.id), ctx.voidPromise());
}
}