package org.bitionaire.elbombillo.account.resources;
import com.fasterxml.jackson.annotation.JsonView;
import com.google.common.base.Optional;
import com.wordnik.swagger.annotations.*;
import io.dropwizard.auth.Auth;
import lombok.extern.slf4j.Slf4j;
import org.bitionaire.elbombillo.account.api.ApiConstant;
import org.bitionaire.elbombillo.account.api.ApiVersion;
import org.bitionaire.elbombillo.account.model.Account;
import org.bitionaire.elbombillo.account.model.AccountListRepresentation;
import org.bitionaire.elbombillo.account.core.auth.AccountServiceCaller;
import org.bitionaire.elbombillo.account.persistence.dao.AccountDAO;
import org.bitionaire.elbombillo.account.model.AccountRepresentation;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.net.URISyntaxException;
@Slf4j
@Path("/accounts") @Api("/accounts")
@Consumes({ ApiVersion.DEFAULT_VERSION, ApiVersion.VERSION_1 })
@Produces({ ApiVersion.DEFAULT_VERSION, ApiVersion.VERSION_1 })
public class AccountResource {
private final AccountDAO accountDAO;
public AccountResource(final AccountDAO accountDAO) {
this.accountDAO = accountDAO;
}
@GET
@JsonView(AccountRepresentation.Abbreviated.class)
@ApiOperation(value = "get all accounts", response = AccountListRepresentation.class)
public Optional<AccountListRepresentation> getAll(@ApiParam("the page of the list") @QueryParam("page") @DefaultValue("1") final int page,
@ApiParam("the maximum number of accounts") @QueryParam("limit") final Integer limit) {
final long countAccounts = accountDAO.countAccounts();
int resultsLimit = Optional.fromNullable(limit).or(ApiConstant.DEFAULT_LIST_PAGE_SIZE);
if (resultsLimit < 1 || resultsLimit > 100) {
resultsLimit = ApiConstant.DEFAULT_LIST_PAGE_SIZE;
}
final int maxPage;
if (countAccounts % resultsLimit == 0) {
maxPage = (int) (countAccounts / resultsLimit);
} else {
maxPage = (int) ((countAccounts / resultsLimit) + 1);
}
if (page > maxPage || page < 1) {
return Optional.absent();
}
return Optional.of(new AccountListRepresentation(accountDAO.allAccounts(resultsLimit, resultsLimit * (page - 1)), page, maxPage));
}
@GET
@JsonView(AccountRepresentation.Complete.class)
@Path("/{id : \\d+}")
@ApiOperation(value = "get an account by id", response = Account.class)
public Optional<Account> get(@ApiParam("the id of the account") @PathParam("id") final long id) {
return Optional.fromNullable(accountDAO.findAccount(id));
}
@GET
@JsonView(AccountRepresentation.Complete.class)
@Path("/{username : [a-zA-Z][a-zA-Z_0-9]+}")
@ApiOperation(value = "get an account by username", response = Account.class)
public Optional<Account> get(@ApiParam("the username of the account") @PathParam("username") final String username) {
return Optional.fromNullable(accountDAO.findAccount(username));
}
@POST
@ApiOperation("add an account")
public Response create(@Context final UriInfo uriInfo, @Auth final AccountServiceCaller caller, final Account account) {
log.info("about to create account {}", account);
final long id = accountDAO.insertAccount(account);
try {
return Response.created(new URI(uriInfo.getAbsolutePath().toString() + "/" + id)).build();
} catch (final URISyntaxException e) {
log.error("failed to create entity location", e);
return Response.serverError().build();
}
}
@PUT
@ApiOperation("update an account")
public Response update(@Auth final AccountServiceCaller caller, final Account account) {
final Account oldAccount = accountDAO.findAccount(account.getUsername());
if (!oldAccount.equals(account)) {
accountDAO.updateAccount(account);
}
return Response.ok().build();
}
@DELETE
@Path("/{id : \\d+}")
@ApiOperation("delete an account by id")
public Response delete(@Auth final AccountServiceCaller caller, @ApiParam("the id of the account") @PathParam("id") final long id) {
accountDAO.deleteUser(id);
return Response.ok().build();
}
@DELETE
@Path("/{username : [a-zA-Z][a-zA-Z_0-9]+}")
@ApiOperation("delete an account by username")
public Response delete(@Auth final AccountServiceCaller caller, @ApiParam("the username of the account") @PathParam("username") final String username) {
accountDAO.deleteUser(username);
return Response.ok().build();
}
}