package com.atlassian.bitbucket.internal.key.ssh.rest;

import com.atlassian.bitbucket.internal.ssh.rest.RestSshKey;
import com.atlassian.bitbucket.permission.Permission;
import com.atlassian.bitbucket.project.Project;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.rest.RestMapEntity;
import com.atlassian.bitbucket.rest.project.RestProject;
import com.atlassian.bitbucket.rest.repository.RestRepository;
import com.atlassian.bitbucket.rest.util.RestPage;
import com.atlassian.bitbucket.ssh.SshAccessKey;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import java.util.function.Function;

import static com.atlassian.bitbucket.rest.util.RestDocUtils.pageOf;

@JsonSerialize
public class RestSshAccessKey extends RestMapEntity {

    private static final String KEY = "key";
    private static final String PROJECT = "project";
    private static final String REPOSITORY = "repository";
    private static final String PERMISSION = "permission";

    public static final Function<SshAccessKey, RestSshAccessKey> REST_TRANSFORM = RestSshAccessKey::new;

    // for Jersey
    public RestSshAccessKey() {
    }

    public RestSshAccessKey(RestSshKey key, RestProject project, RestRepository repository, Permission permission) {
        put(KEY, key);
        if (project != null) {
            put(PROJECT, project);
        }
        if (repository != null) {
            put(REPOSITORY, repository);
        }
        put(PERMISSION, permission);
    }

    public RestSshAccessKey(SshAccessKey accessKey) {
        put(KEY, new RestSshKey(accessKey.getKey()));

        Object resource = accessKey.getResource();
        if (resource instanceof Project) {
            put(PROJECT, new RestProject((Project) resource));
        } else {
            put(REPOSITORY, new RestRepository((Repository) resource));
        }
        put(PERMISSION, accessKey.getPermission().name());
    }

    public RestSshKey getKey() {
        return RestSshKey.valueOf(get(KEY));
    }

    public Permission getPermission() {
        if (containsKey(PERMISSION)) {
            return Permission.valueOf(getStringProperty(PERMISSION));
        }
        return null;
    }

    public RestProject getProject() {
        return RestProject.valueOf(get(PROJECT));
    }

    public RestRepository getRepository() {
        return RestRepository.valueOf(get(REPOSITORY));
    }

    public boolean hasKey() {
        return getKey() != null;
    }

    public boolean hasPermission() {
        return containsKey(PERMISSION);
    }

    public boolean hasProject() {
        return getProject() != null;
    }

    public boolean hasRepository() {
        return getRepository() != null;
    }

    // REST documentation examples
    public static final RestSshAccessKey PROJECT_REQUEST_EXAMPLE = new RestSshAccessKey(
            RestSshKey.EXAMPLE_REQUEST, null, null, Permission.PROJECT_READ);
    public static final RestSshAccessKey PROJECT_RESPONSE_EXAMPLE = new RestSshAccessKey(
            RestSshKey.EXAMPLE_RESPONSE, RestProject.RESPONSE_EXAMPLE, null, Permission.PROJECT_READ);
    public static final RestSshAccessKey REPOSITORY_REQUEST_EXAMPLE = new RestSshAccessKey(
            RestSshKey.EXAMPLE_REQUEST, null, null, Permission.REPO_WRITE);
    public static final RestSshAccessKey REPOSITORY_RESPONSE_EXAMPLE = new RestSshAccessKey(
            RestSshKey.EXAMPLE_REQUEST, null, RestRepository.RESPONSE_EXAMPLE, Permission.REPO_WRITE);
    public static final RestPage<RestSshAccessKey> PAGE_PROJECT_EXAMPLE = pageOf(PROJECT_RESPONSE_EXAMPLE);
    public static final RestPage<RestSshAccessKey> PAGE_REPOSITORY_EXAMPLE = pageOf(REPOSITORY_RESPONSE_EXAMPLE);

}
