/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.usergrid.rest;


import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
import com.google.common.collect.BiMap;
import com.google.inject.Injector;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.*;
import com.yammer.metrics.stats.Snapshot;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.usergrid.corepersistence.asyncevents.AsyncEventService;
import org.apache.usergrid.persistence.core.util.Health;
import org.apache.usergrid.persistence.index.query.Identifier;
import org.apache.usergrid.rest.applications.ApplicationResource;
import org.apache.usergrid.rest.exceptions.NoOpException;
import org.apache.usergrid.rest.organizations.OrganizationResource;
import org.apache.usergrid.rest.security.annotations.RequireSystemAccess;
import org.apache.usergrid.system.UsergridSystemMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.SortedMap;
import java.util.UUID;


/** @author ed@anuff.com */
@Path("/")
@Component
@Scope("singleton")
@Produces({
        MediaType.APPLICATION_JSON, "application/javascript", "application/x-javascript", "text/ecmascript",
        "application/ecmascript", "text/jscript"
})
public class RootResource extends AbstractContextResource implements MetricProcessor<RootResource.MetricContext> {

    static final class MetricContext {
        final boolean showFullSamples;
        final ObjectNode objectNode;


        MetricContext( ObjectNode objectNode, boolean showFullSamples ) {
            this.objectNode = objectNode;
            this.showFullSamples = showFullSamples;
        }
    }


    private static final Logger logger = LoggerFactory.getLogger( RootResource.class );

    long started = System.currentTimeMillis();

    @Autowired
    private UsergridSystemMonitor usergridSystemMonitor;

    @Autowired
    private Injector injector;


    public RootResource() {
    }


    @RequireSystemAccess
    @GET
    @Path("applications")
    @JSONP
    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
    public ApiResponse getAllApplications(
        @Context UriInfo ui,
        @QueryParam("deleted") @DefaultValue("false") Boolean deleted,
        @QueryParam("callback") @DefaultValue("callback") String callback ) throws URISyntaxException {

        if (logger.isTraceEnabled()) {
            logger.trace("RootResource.getData");
        }

        ApiResponse response = createApiResponse();
        response.setAction( "get applications" );

        Map<String, UUID> applications = null;
        try {
            if ( deleted ) {
                applications = emf.getDeletedApplications();
            } else {
                applications = emf.getApplications();
            }
            response.setSuccess();
            response.setApplications( applications );
        }
        catch ( Exception e ) {
            logger.info( "Unable to retrieve applications", e );
            response.setError( "Unable to retrieve applications" );
        }

        return response;
    }


    @RequireSystemAccess
    @GET
    @Path("apps")
    @JSONP
    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
    public ApiResponse getAllApplications2( @Context UriInfo ui,
                                                @QueryParam("callback") @DefaultValue("callback") String callback )
            throws URISyntaxException {
        return getAllApplications( ui, false, callback );
    }


    @GET
    public Response getRoot( @Context UriInfo ui ) throws URISyntaxException {

        String redirect_root = properties.getRedirectRoot();
        if ( StringUtils.isNotBlank( redirect_root ) ) {
            ResponseBuilder response = Response.temporaryRedirect( new URI( redirect_root ) );
            return response.build();
        }
        else {
            ResponseBuilder response = Response.temporaryRedirect( new URI( "/status" ) );
            return response.build();
        }
    }


    /**
     * Return status of this Usergrid instance in JSON format.
     *
     * By Default this end-point will ignore errors but if you call it with ignore_status=false
     * then it will return HTTP 500 if either the Entity store or the Index for the management
     * application are in a bad state.
     *
     * @param ignoreError Ignore any errors and return status no matter what.
     */
    @GET
    @Path("status")
    @JSONP
    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
    public ApiResponse getStatus(
            @QueryParam("ignore_error") @DefaultValue("true") Boolean ignoreError,
            @QueryParam("callback") @DefaultValue("callback") String callback ) {

        ApiResponse response = createApiResponse();

        if ( !ignoreError ) {

            if ( !emf.getEntityStoreHealth().equals( Health.GREEN )) {
                throw new RuntimeException("Error connecting to datastore");
            }


            if ( emf.getIndexHealth().equals( Health.RED) ) {
                throw new RuntimeException("Management app index is status RED");
            }
        }

        ObjectNode node = JsonNodeFactory.instance.objectNode();
        node.put( "started", started );
        node.put( "uptime", System.currentTimeMillis() - started );
        node.put( "version", usergridSystemMonitor.getBuildNumber());

        // Hector status, for backwards compatibility
        node.put("cassandraAvailable", usergridSystemMonitor.getIsCassandraAlive());

        // Core Persistence Collections module status
        node.put( "cassandraStatus", emf.getEntityStoreHealth().toString() );

        // Core Persistence Query Index module status for Management App Index
        node.put( "managementAppIndexStatus", emf.getIndexHealth().toString() );


        dumpMetrics(node);
        response.setProperty( "status", node );
        return response;
    }


    @GET
    @Path("lb-status")
    @JSONP
    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
    public Response getLbStatus() {
        ResponseBuilder response;
        if ( usergridSystemMonitor.getIsCassandraAlive() ) {
            response = Response.noContent().status( Response.Status.OK );
        }
        else {
            response = Response.noContent().status( Response.Status.SERVICE_UNAVAILABLE );
        }
        return response.build();
    }

    @GET
    @Path("/status/queue")
    @JSONP
    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
    public ApiResponse getQueueDepth(){

        ApiResponse response = createApiResponse();
        AsyncEventService eventService = injector.getInstance(AsyncEventService.class);

        ObjectNode node = JsonNodeFactory.instance.objectNode();

        String provider = "LOCAL";
        String queueManagerClass = eventService.getQueueManagerClass();

        if(queueManagerClass.contains("SNS") || queueManagerClass.contains("SQS")){
            provider = "AWS";
        }

        node.put( "provider", provider );
        node.put( "depth", eventService.getQueueDepth() );

        response.setProperty( "status", node );
        return response;

    }

    @GET
    @Path("/status/heap")
    @JSONP
    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
    public ApiResponse getHeapStats(){

        ApiResponse response = createApiResponse();

        ObjectNode node = JsonNodeFactory.instance.objectNode();

        long heapAllocatedSize = Runtime.getRuntime().totalMemory();
        long heapMaxSize = Runtime.getRuntime().maxMemory();
        long heapFreeSize = Runtime.getRuntime().freeMemory();
        long heapUsedSize = heapAllocatedSize - heapFreeSize;

        node.put( "used", org.apache.usergrid.utils.StringUtils.readableByteSize(heapUsedSize) );
        node.put( "free", org.apache.usergrid.utils.StringUtils.readableByteSize(heapFreeSize) );
        node.put( "allocated", org.apache.usergrid.utils.StringUtils.readableByteSize(heapAllocatedSize) );
        node.put( "max", org.apache.usergrid.utils.StringUtils.readableByteSize(heapMaxSize) );

        response.setProperty( "status", node );
        return response;

    }



    private void dumpMetrics( ObjectNode node ) {
        MetricsRegistry registry = Metrics.defaultRegistry();

        for ( Map.Entry<String, SortedMap<MetricName, Metric>> entry : registry.groupedMetrics().entrySet() ) {

            ObjectNode meterNode = JsonNodeFactory.instance.objectNode();

            for ( Map.Entry<MetricName, Metric> subEntry : entry.getValue().entrySet() ) {
                ObjectNode metricNode = JsonNodeFactory.instance.objectNode();

                try {
                    subEntry.getValue().processWith( this, subEntry.getKey(), new MetricContext( metricNode, true ) );
                }
                catch ( Exception e ) {
                    logger.warn( "Error writing out {}", subEntry.getKey(), e );
                }
                meterNode.put( subEntry.getKey().getName(), metricNode );
            }
            node.put( entry.getKey(), meterNode );
        }
    }


    @Path("{applicationId: [A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}}")
    public ApplicationResource getApplicationById( @PathParam("applicationId") String applicationIdStr )
            throws Exception {

        if ( "options".equalsIgnoreCase( request.getMethod() ) ) {
            throw new NoOpException();
        }

        UUID applicationId = UUID.fromString( applicationIdStr );
        if ( applicationId == null ) {
            return null;
        }

        return appResourceFor( applicationId );
    }


    private ApplicationResource appResourceFor( UUID applicationId ) throws Exception {
        if ( applicationId.equals( emf.getManagementAppId() ) ) {
            throw new UnauthorizedException();
        }

        return getSubResource( ApplicationResource.class ).init( applicationId );
    }


    @Path("applications/"+APPLICATION_ID_PATH)
    public ApplicationResource getApplicationById2( @PathParam("applicationId") String applicationId )
            throws Exception {
        return getApplicationById( applicationId );
    }


    @Path("apps/"+APPLICATION_ID_PATH)
    public ApplicationResource getApplicationById3( @PathParam("applicationId") String applicationId )
            throws Exception {
        return getApplicationById( applicationId );
    }

    public static final String APPLICATION_ID_PATH = "{applicationId: " + Identifier.UUID_REX + "}";
    public static final String ORGANIZATION_ID_PATH = "{organizationId: " + Identifier.UUID_REX + "}";
    public static final String USER_ID_PATH = "{userId: " + Identifier.UUID_REX + "}";
    public static final String ENTITY_ID_PATH = "{entityId: " + Identifier.UUID_REX + "}";
    public static final String EMAIL_PATH = "{email: " + Identifier.EMAIL_REX + "}";

    @Path(ORGANIZATION_ID_PATH+"/"+APPLICATION_ID_PATH)
    public ApplicationResource getApplicationByUuids( @PathParam("organizationId") String organizationIdStr,
                                                      @PathParam("applicationId") String applicationIdStr )

            throws Exception {

        UUID applicationId = UUID.fromString( applicationIdStr );
        UUID organizationId = UUID.fromString( organizationIdStr );
        if ( applicationId == null || organizationId == null ) {
            return null;
        }
        BiMap<UUID, String> apps = management.getApplicationsForOrganization( organizationId );
        if ( apps.get( applicationId ) == null ) {
            return null;
        }
        return appResourceFor( applicationId );
    }


    private OrganizationResource orgResourceFor( String organizationName ) throws Exception {

        return getSubResource( OrganizationResource.class ).init( organizationName );
    }


    @Path("{organizationName}")
    public OrganizationResource getOrganizationByName( @PathParam("organizationName") String organizationName )
            throws Exception {

        if ( "options".equalsIgnoreCase( request.getMethod() ) ) {
            throw new NoOpException();
        }

        return orgResourceFor( organizationName );
    }


    @Path("organizations/{organizationName}")
    public OrganizationResource getOrganizationByName2( @PathParam("organizationName") String organizationName )
            throws Exception {
        return getOrganizationByName( organizationName );
    }


    @Path("orgs/{organizationName}")
    public OrganizationResource getOrganizationByName3( @PathParam("organizationName") String organizationName )
            throws Exception {
        if (logger.isTraceEnabled()) {
            logger.trace("getOrganizationByName3");
        }

        return getOrganizationByName( organizationName );
    }


    @Path("o/{organizationName}")
    public OrganizationResource getOrganizationByName4( @PathParam("organizationName") String organizationName )
            throws Exception {
        return getOrganizationByName( organizationName );
    }


    @Override
    public void processHistogram( MetricName name, Histogram histogram, MetricContext context ) throws Exception {
        final ObjectNode node = context.objectNode;
        node.put( "type", "histogram" );
        node.put( "count", histogram.count() );
        writeSummarizable( histogram, node );
        writeSampling( histogram, node );
    }


    @Override
    public void processCounter( MetricName name, Counter counter, MetricContext context ) throws Exception {
        final ObjectNode node = context.objectNode;
        node.put( "type", "counter" );
        node.put( "count", counter.count() );
    }


    @Override
    public void processGauge( MetricName name, Gauge<?> gauge, MetricContext context ) throws Exception {
        final ObjectNode node = context.objectNode;
        node.put( "type", "gauge" );
        node.put( "vale", "[disabled]" );
    }


    @Override
    public void processMeter( MetricName name, Metered meter, MetricContext context ) throws Exception {
        final ObjectNode node = context.objectNode;
        node.put( "type", "meter" );
        node.put( "event_type", meter.eventType() );
        writeMeteredFields( meter, node );
    }


    @Override
    public void processTimer( MetricName name, Timer timer, MetricContext context ) throws Exception {
        final ObjectNode node = context.objectNode;

        node.put( "type", "timer" );
        // json.writeFieldName("duration");
        node.put( "unit", timer.durationUnit().toString().toLowerCase() );
        ObjectNode durationNode = JsonNodeFactory.instance.objectNode();
        writeSummarizable( timer, durationNode );
        writeSampling( timer, durationNode );
        node.put( "duration", durationNode );
        writeMeteredFields( timer, node );
    }


    private static void writeSummarizable( Summarizable metric, ObjectNode mNode ) throws IOException {
        mNode.put( "min", metric.min() );
        mNode.put( "max", metric.max() );
        mNode.put( "mean", metric.mean() );
        mNode.put( "std_dev", metric.stdDev() );
    }


    private static void writeSampling( Sampling metric, ObjectNode mNode ) throws IOException {

        final Snapshot snapshot = metric.getSnapshot();
        mNode.put( "median", snapshot.getMedian() );
        mNode.put( "p75", snapshot.get75thPercentile() );
        mNode.put( "p95", snapshot.get95thPercentile() );
        mNode.put( "p98", snapshot.get98thPercentile() );
        mNode.put( "p99", snapshot.get99thPercentile() );
        mNode.put( "p999", snapshot.get999thPercentile() );
    }


    private static void writeMeteredFields( Metered metered, ObjectNode node ) throws IOException {
        ObjectNode mNode = JsonNodeFactory.instance.objectNode();
        mNode.put( "unit", metered.rateUnit().toString().toLowerCase() );
        mNode.put( "count", metered.count() );
        mNode.put( "mean", metered.meanRate() );
        mNode.put( "m1", metered.oneMinuteRate() );
        mNode.put( "m5", metered.fiveMinuteRate() );
        mNode.put( "m15", metered.fifteenMinuteRate() );
        node.put( "rate", mNode );
    }
}
