/**
 * © David Attias 2015
 */
package io.spacedog.services.snapshot;

import java.util.List;

import io.spacedog.client.credentials.Credentials;
import io.spacedog.client.snapshot.SpaceRepository;
import io.spacedog.client.snapshot.SpaceSnapshot;
import io.spacedog.server.JsonPayload;
import io.spacedog.server.Server;
import io.spacedog.server.Services;
import io.spacedog.server.SpaceResty;
import io.spacedog.utils.Exceptions;
import net.codestory.http.Context;
import net.codestory.http.annotations.Delete;
import net.codestory.http.annotations.Get;
import net.codestory.http.annotations.Post;
import net.codestory.http.annotations.Prefix;
import net.codestory.http.constants.HttpStatus;
import net.codestory.http.payload.Payload;

@Prefix("/2/snapshots")
public class SnapshotResty extends SpaceResty {

	public static final String SNAPSHOTER_ROLE = "snapshoter";

	//
	// routes
	//

	@Get("")
	@Get("/")
	public List<SpaceSnapshot> getAll(Context context) {
		checkSnapshotOrSuperadmin();
		int from = context.query().getInteger(FROM_PARAM, 0);
		int size = context.query().getInteger(SIZE_PARAM, 10);
		return Services.snapshots().getLatest(from, size);
	}

	@Post("")
	@Post("/")
	public Payload postSnapshot(Context context) {
		checkSnapshotOrSuperadmin();
		boolean wait = context.query().getBoolean(WAIT_FOR_COMPLETION_PARAM, false);
		return JsonPayload.status(wait ? 202 : 201)//
				.withContent(Services.snapshots().snapshot(wait))//
				.build();
	}

	@Get("/repositories")
	@Get("/repositories/")
	public List<SpaceRepository> getRepositories(Context context) {
		checkSnapshotOrSuperadmin();
		return Services.snapshots().getRepositories();
	}

	@Delete("/repositories/:id")
	@Delete("/repositories/:id/")
	public Payload deleteRepository(String id, Context context) {
		Server.context().credentials().checkAtLeastSuperAdmin();
		boolean found = Services.snapshots().deleteRepository(id);
		return JsonPayload.ok().withFields("found", found).build();
	}

	@Get("/_latest")
	@Get("/_latest/")
	public SpaceSnapshot getLatest() {
		checkSnapshotOrSuperadmin();
		return Services.snapshots().getLatest(0, 1)//
				.stream().findAny()//
				.orElseThrow(() -> Exceptions.notFound("no snapshot found"));
	}

	@Get("/:id")
	@Get("/:id/")
	public SpaceSnapshot getById(String snapshotId) {
		checkSnapshotOrSuperadmin();
		return Services.snapshots().get(snapshotId)//
				.orElseThrow(() -> Exceptions.notFound("snapshot [%s] not found", snapshotId));
	}

	@Post("/_latest/_restore")
	@Post("/_latest/_restore/")
	public Payload postRestoreLatest(Context context) {
		Server.context().credentials().checkAtLeastSuperAdmin();
		return Services.snapshots().getLatest(0, 1).stream().findAny()//
				.map(snapshot -> postRestoreById(snapshot.id, context))//
				.orElseThrow(() -> Exceptions.notFound("no snapshot found"));
	}

	@Post("/:id/_restore")
	@Post("/:id/_restore/")
	public Payload postRestoreById(String snapshotId, Context context) {
		Server.context().credentials().checkAtLeastSuperAdmin();
		boolean wait = context.query().getBoolean(WAIT_FOR_COMPLETION_PARAM, false);
		Services.snapshots().restore(snapshotId, wait);
		return wait ? Payload.ok() : new Payload(HttpStatus.ACCEPTED);
	}

	//
	// implementation
	//

	private void checkSnapshotOrSuperadmin() {
		Credentials credentials = Server.context().credentials();

		if (credentials.isAtLeastSuperAdmin() || isSnapshot(credentials))
			return;

		throw Exceptions.insufficientPermissions(credentials);
	}

	private boolean isSnapshot(Credentials credentials) {
		return credentials.roles().contains(SNAPSHOTER_ROLE);
	}

}

@@ -840,23 +840,20 @@
 SNAPSHOT
-ER_ROLE
+_MAN
  = %22snap
@@ -856,18 +856,19 @@
 snapshot
-er
+man
 %22;%0A%0A%09//%0A
@@ -961,32 +961,39 @@
 t) %7B%0A%09%09check
+AtLeast
 Snapshot
 OrSuperadmin
@@ -976,35 +976,26 @@
 eastSnapshot
-OrSuperadmi
+Ma
 n();%0A%09%09int f
@@ -1231,32 +1231,39 @@
 t) %7B%0A%09%09check
+AtLeast
 Snapshot
 OrSuperadmin
@@ -1246,35 +1246,26 @@
 eastSnapshot
-OrSuperadmi
+Ma
 n();%0A%09%09boole
@@ -1573,32 +1573,39 @@
 t) %7B%0A%09%09check
+AtLeast
 Snapshot
 OrSuperadmin
@@ -1588,35 +1588,26 @@
 eastSnapshot
-OrSuperadmi
+Ma
 n();%0A%09%09retur
@@ -2038,32 +2038,39 @@
 () %7B%0A%09%09check
+AtLeast
 Snapshot
 OrSuperadmin
@@ -2053,35 +2053,26 @@
 eastSnapshot
-OrSuperadmi
+Ma
 n();%0A%09%09retur
@@ -2291,32 +2291,39 @@
 d) %7B%0A%09%09check
+AtLeast
 Snapshot
 OrSuperadmin
@@ -2310,27 +2310,18 @@
 Snapshot
-OrSuperadmi
+Ma
 n();%0A%09%09r
@@ -3238,37 +3238,42 @@
 ate 
-void checkSnapshotOrSuperadmi
+Credentials checkAtLeastSnapshotMa
 n() 
@@ -3379,217 +3379,140 @@
 n() 
-%7C%7C isSnapshot(credentials))%0A%09%09%09return;%0A%0A%09%09throw Exceptions.insufficientPermissions(credentials);%0A%09%7D%0A%0A%09private boolean isSnapshot(Credentials credentials) %7B%0A%09%09return credentials.roles().contains(SNAPSHOTER_ROLE
+//%0A%09%09%09%09%7C%7C credentials.roles().contains(SNAPSHOT_MAN))%0A%09%09%09return credentials;%0A%0A%09%09throw Exceptions.insufficientPermissions(credentials
 );%0A%09

Rename role authorized to snapshot backend