/*
 * 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.applications.kvm;

import com.google.inject.Injector;
import org.apache.commons.lang.StringUtils;
import org.apache.usergrid.persistence.map.MapKeyResults;
import org.apache.usergrid.persistence.map.MapManager;
import org.apache.usergrid.persistence.map.MapManagerFactory;
import org.apache.usergrid.persistence.map.MapScope;
import org.apache.usergrid.persistence.map.impl.MapScopeImpl;
import org.apache.usergrid.rest.AbstractContextResource;
import org.apache.usergrid.rest.ApiResponse;
import org.apache.usergrid.rest.applications.ServiceResource;
import org.apache.usergrid.services.ServiceManager;
import org.apache.usergrid.utils.JsonUtils;
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 rx.Observable;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import java.util.*;

@Component("org.apache.usergrid.rest.applications.kvm.KvmResource")
@Scope("prototype")
@Produces(MediaType.APPLICATION_JSON)
public class KvmResource extends AbstractContextResource {

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


    private final int PAGE_SIZE_MAX = 1000;
    private final int PAGE_SIZE_DEFAULT = 10;
    private final int BATCH_SIZE_MAX = 10;

    ServiceManager services = null;

    @Autowired
    private Injector injector;

    public KvmResource(){
        if(logger.isTraceEnabled()) {
            logger.trace("kvm.KvmResource");
        }
    }

    @Override
    public void setParent( AbstractContextResource parent ) {
        super.setParent( parent );
        if ( parent instanceof ServiceResource ) {
            services = ( ( ServiceResource ) parent ).services;
        }
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ApiResponse createMap( @Context UriInfo ui,
                                  Map<String, Object> json ) {

        if( json.keySet().size() < 1 ){
            throw new IllegalArgumentException("New map must be specified");
        }
        if( json.keySet().size() > 1 ){
            throw new IllegalArgumentException("Only 1 map can be created at a time.");
        }

        enforceQueryFeature(ui);

        final String mapName = json.keySet().iterator().next();

        if( !(json.get(mapName) instanceof Map) ){
            throw new IllegalArgumentException("New map details must be provided as a JSON object.");
        }
        final Map<String, Object> meta = (Map<String, Object>)json.get(mapName);

        if(StringUtils.isEmpty(mapName)){
            throw new IllegalArgumentException("Property mapName is required.");
        }

        if( json.containsKey("metadata") ){
            json.remove("metadata");
        }

        final String appMap = services.getApplicationId().toString();
        final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), appMap);
        final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
        final MapManager mapManager = mmf.createMapManager(mapScope);

        final Map<String, Object> mapDetails = new HashMap<String, Object>(){{
            put("metadata", new HashMap<String, Object>(){{
                put("active", true);
                put("modified", System.currentTimeMillis() );
            }});
            putAll(meta);

        }};

        mapManager.putString(mapName, JsonUtils.mapToJsonString(mapDetails));

        // This used for response format
        final Map<String, Object> map = new HashMap<>(2);
        map.put(mapName, mapDetails);


        ApiResponse response = createApiResponse();
        response.setAction( "post" );
        response.setApplication( services.getApplication() );
        response.setParams( ui.getQueryParameters() );
        response.setProperty("maps", map);

        return response;

    }


    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public ApiResponse getMaps( @Context UriInfo ui,
                                @QueryParam("limit") int limit,
                                @QueryParam("cursor") String cursor) {

        limit = validateLimit(limit);
        enforceQueryFeature(ui);

        final String appMap = services.getApplicationId().toString();

        final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), appMap);
        final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
        final MapManager mapManager = mmf.createMapManager(mapScope);

        MapKeyResults mapKeyResults = mapManager.getKeys(cursor, limit );

        Map<String, Object> results = new HashMap<>();

        Observable.from(mapKeyResults.getKeys()).flatMap(key -> {
            return Observable.just(results.put(key, JsonUtils.parse(mapManager.getString(key))));

        }).toBlocking().lastOrDefault(null);


        ApiResponse response = createApiResponse();
        response.setAction( "get" );
        response.setApplication( services.getApplication() );
        response.setParams( ui.getQueryParameters() );
        response.setProperty("maps", results);

        if( StringUtils.isNotEmpty(mapKeyResults.getCursor())){
            response.setProperty("cursor", mapKeyResults.getCursor());
        }

        return response;

    }

    @GET
    @Path("{mapName}")
    @Produces(MediaType.APPLICATION_JSON)
    public ApiResponse getSingleMap( @Context UriInfo ui,
                                @QueryParam("limit") int limit,
                                @QueryParam("cursor") String cursor,
                                @PathParam("mapName") String mapName ) {

        limit = validateLimit(limit);
        enforceQueryFeature(ui);

        final String appMap = services.getApplicationId().toString();

        final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), appMap);
        final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
        final MapManager mapManager = mmf.createMapManager(mapScope);


        Map<String, Object> map = new HashMap<>();
        map.put(mapName, JsonUtils.parse(mapManager.getString(mapName)));


        ApiResponse response = createApiResponse();
        response.setAction( "get" );
        response.setApplication( services.getApplication() );
        response.setParams( ui.getQueryParameters() );
        response.setProperty("maps", map);

        return response;

    }


    @POST
    @Path("{mapName}/entries")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ApiResponse createEntries( @Context UriInfo ui,
                                      Map<String,Object> json,
                                      @PathParam("mapName") String mapName ) {

        if ( json.size() > BATCH_SIZE_MAX ){
            throw new IllegalArgumentException("Batch size "+json.size()+" is more than max size of "+BATCH_SIZE_MAX);
        }

        if(StringUtils.isEmpty(mapName)){
            throw new IllegalArgumentException("Property mapName is required.");
        }

        enforceQueryFeature(ui);

        final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), mapName);
        final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
        final MapManager mapManager = mmf.createMapManager(mapScope);

        //TODO maybe RX flatmap this or parallel stream
        json.forEach( (key, value) -> {

            mapManager.putString(key, value.toString());

        });


        ApiResponse response = createApiResponse();
        response.setAction( "post" );
        response.setApplication( services.getApplication() );
        response.setParams( ui.getQueryParameters() );
        response.setProperty("entries", json);

        return response;

    }

    @GET
    @Path("{mapName}/keys")
    @Produces(MediaType.APPLICATION_JSON)
    public ApiResponse getKeys( @Context UriInfo ui,
                                @QueryParam("limit") int limit,
                                @QueryParam("cursor") String cursor,
                                @PathParam("mapName") String mapName ) {


        if(StringUtils.isEmpty(mapName)){
            throw new IllegalArgumentException("Property mapName is required.");
        }

        limit = validateLimit(limit);
        enforceQueryFeature(ui);

        final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), mapName);
        final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
        final MapManager mapManager = mmf.createMapManager(mapScope);

        MapKeyResults mapKeyResults = mapManager.getKeys(cursor, limit );

        ApiResponse response = createApiResponse();
        response.setAction( "get" );
        response.setApplication( services.getApplication() );
        response.setParams( ui.getQueryParameters() );
        response.setProperty("keys", mapKeyResults.getKeys());

        if( StringUtils.isNotEmpty(mapKeyResults.getCursor())){
            response.setProperty("cursor", mapKeyResults.getCursor());
        }

        return response;

    }

    @GET
    @Path("{mapName}/entries")
    @Produces(MediaType.APPLICATION_JSON)
    public ApiResponse getEntries( @Context UriInfo ui,
                                   @QueryParam("limit") int limit,
                                   @QueryParam("cursor") String cursor,
                                   @PathParam("mapName") String mapName ) {

        if(StringUtils.isEmpty(mapName)){
            throw new IllegalArgumentException("Property mapName is required.");
        }

        limit = validateLimit(limit);
        enforceQueryFeature(ui);

        final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), mapName);
        final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
        final MapManager mapManager = mmf.createMapManager(mapScope);

        MapKeyResults mapKeyResults = mapManager.getKeys(cursor, limit );

        Map<String, Object> results = new HashMap<>();
        Observable.from(mapKeyResults.getKeys()).flatMap(key ->{
            return Observable.just(results.put(key, mapManager.getString(key)));
        }).toBlocking().lastOrDefault(null);


        ApiResponse response = createApiResponse();
        response.setAction( "get" );
        response.setApplication( services.getApplication() );
        response.setParams( ui.getQueryParameters() );
        response.setProperty("entries", results);

        if( StringUtils.isNotEmpty(mapKeyResults.getCursor())){
            response.setProperty("cursor", mapKeyResults.getCursor());
        }

        return response;

    }

    @GET
    @Path("{mapName}/entries/{keyName}")
    @Produces(MediaType.APPLICATION_JSON)
    public Object getEntry( @Context UriInfo ui,
                                   @PathParam("mapName") String mapName,
                                   @PathParam("keyName") String keyName,
                                   @QueryParam("rawData") @DefaultValue("false") boolean rawData) {

        enforceQueryFeature(ui);

        final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), mapName);
        final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
        final MapManager mapManager = mmf.createMapManager(mapScope);


        Map<String, Object> results = new HashMap<>();
        Object value = mapManager.getString(keyName);
        results.put(keyName, value);

        if( !rawData ) {
            ApiResponse response = createApiResponse();
            response.setAction("get");
            response.setApplication(services.getApplication());
            response.setParams(ui.getQueryParameters());
            response.setProperty("entries", results);
            return response;
        }else{
            return value;
        }



    }


    private int validateLimit(final int limit){

        return limit > 0 && limit < PAGE_SIZE_MAX ? limit : PAGE_SIZE_DEFAULT;

    }

    private void enforceQueryFeature(UriInfo ui) {

        if( StringUtils.isNotEmpty(ui.getQueryParameters().getFirst("ql"))){

            throw new IllegalArgumentException("Query feature not supported for keyvaluemaps");

        }

    }


}
