/**
 * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.eclipse.hawkbit.dmf.json.model;

import java.util.Map;
import java.util.TreeMap;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * JSON representation to authenticate a tenant.
 */

@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class TenantSecurityToken {

    public static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String COAP_AUTHORIZATION_HEADER = "Coap-Authorization";
    public static final String COAP_TOKEN_VALUE = "CoapToken";

    @JsonProperty
    private final String tenant;
    @JsonProperty
    private final String controllerId;
    @JsonProperty(required = false)
    private Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

    @JsonProperty(required = false)
    private final FileResource fileResource;

    /**
     * Constructor.
     * 
     * @param tenant
     *            the tenant for the security token
     * @param controllerId
     *            the ID of the controller for the security token
     * @param fileResource
     *            the file to obtain
     */
    @JsonCreator
    public TenantSecurityToken(@JsonProperty("tenant") final String tenant,
            @JsonProperty("controllerId") final String controllerId,
            @JsonProperty("fileResource") final FileResource fileResource) {
        this.tenant = tenant;
        this.controllerId = controllerId;
        this.fileResource = fileResource;
    }

    public String getTenant() {
        return tenant;
    }

    public String getControllerId() {
        return controllerId;
    }

    public Map<String, String> getHeaders() {
        return headers;
    }

    public FileResource getFileResource() {
        return fileResource;
    }

    /**
     * Gets a header value.
     * 
     * @param name
     *            of header
     * @return the value
     */
    public String getHeader(final String name) {
        return headers.get(name);
    }

    public void setHeaders(final Map<String, String> headers) {
        this.headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        this.headers.putAll(headers);
    }

    /**
     * File resource descriptor which is used to ask for the resource to
     * download e.g. The lookup of the file can be different e.g. by SHA1 hash
     * or by filename.
     */
    @JsonInclude(Include.NON_NULL)
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class FileResource {
        @JsonProperty(required = false)
        private String sha1;
        @JsonProperty(required = false)
        private String filename;
        @JsonProperty(required = false)
        private SoftwareModuleFilenameResource softwareModuleFilenameResource;

        public String getSha1() {
            return sha1;
        }

        public void setSha1(final String sha1) {
            this.sha1 = sha1;
        }

        public String getFilename() {
            return filename;
        }

        public void setFilename(final String filename) {
            this.filename = filename;
        }

        public SoftwareModuleFilenameResource getSoftwareModuleFilenameResource() {
            return softwareModuleFilenameResource;
        }

        public void setSoftwareModuleFilenameResource(
                final SoftwareModuleFilenameResource softwareModuleFilenameResource) {
            this.softwareModuleFilenameResource = softwareModuleFilenameResource;
        }

        /**
         * factory method to create a file resource for an SHA1 lookup.
         * 
         * @param sha1
         *            the SHA1 key of the file to obtain
         * @return the {@link FileResource} with SHA1 key set
         */
        public static FileResource sha1(final String sha1) {
            final FileResource resource = new FileResource();
            resource.sha1 = sha1;
            return resource;
        }

        /**
         * factory method to create a file resource for an filename lookup.
         * 
         * @param filename
         *            the filename of the file to obtain
         * @return the {@link FileResource} with filename set
         */
        public static FileResource filename(final String filename) {
            final FileResource resource = new FileResource();
            resource.filename = filename;
            return resource;
        }

        /**
         * factory method to create a file resource for an softwaremodule +
         * filename lookup, because an filename is not globally unique but
         * within a softwaremodule.
         * 
         * @param softwareModuleId
         *            the ID of the software module which contains the artifact
         * @param filename
         *            the name of file to obtain within the software module
         * @return the {@link FileResource} with artifactId set
         */
        public static FileResource softwareModuleFilename(final Long softwareModuleId, final String filename) {
            final FileResource resource = new FileResource();
            resource.softwareModuleFilenameResource = new SoftwareModuleFilenameResource(softwareModuleId, filename);
            return resource;
        }

        @Override
        public String toString() {
            return "FileResource [sha1=" + sha1 + ", filename=" + filename + "]";
        }

        /**
         * Inner class which holds the pointer to an artifact based on the
         * softwaremoduleId and the filename.
         */
        @JsonInclude(Include.NON_NULL)
        @JsonIgnoreProperties(ignoreUnknown = true)
        public static class SoftwareModuleFilenameResource {
            @JsonProperty(required = false)
            private final Long softwareModuleId;
            @JsonProperty(required = false)
            private final String filename;

            /**
             * Constructor.
             * 
             * @param softwareModuleId
             *            the ID of the softwaremodule
             * @param filename
             *            the name of the file of the artifact within the
             *            softwaremodule
             */
            @JsonCreator
            public SoftwareModuleFilenameResource(@JsonProperty("softwareModuleId") final Long softwareModuleId,
                    @JsonProperty("filename") final String filename) {
                this.softwareModuleId = softwareModuleId;
                this.filename = filename;
            }

            public Long getSoftwareModuleId() {
                return softwareModuleId;
            }

            public String getFilename() {
                return filename;
            }
        }
    }
}

@@ -6275,22 +6275,16 @@
 private 
-final 
 Long sof
@@ -6358,30 +6358,24 @@
     private 
-final 
 String filen
@@ -7208,24 +7208,290 @@
            %7D
+%0A%0A            public void setSoftwareModuleId(final Long softwareModuleId) %7B%0A                this.softwareModuleId = softwareModuleId;%0A            %7D%0A%0A            public void setFilename(final String filename) %7B%0A                this.filename = filename;%0A            %7D
 %0A        %7D%0A 

allow to set the filename and software module id