/**
 * 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.hadoop.gateway.filter.rewrite.api;

import org.apache.hadoop.gateway.filter.rewrite.ext.ScopedMatcher;
import org.apache.hadoop.gateway.filter.rewrite.i18n.UrlRewriteMessages;
import org.apache.hadoop.gateway.filter.rewrite.impl.UrlRewriteContextImpl;
import org.apache.hadoop.gateway.filter.rewrite.impl.UrlRewriteFunctionProcessorFactory;
import org.apache.hadoop.gateway.filter.rewrite.impl.UrlRewriteRuleProcessorHolder;
import org.apache.hadoop.gateway.filter.rewrite.impl.UrlRewriteStepProcessorHolder;
import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteContext;
import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor;
import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepStatus;
import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
import org.apache.hadoop.gateway.util.urltemplate.Matcher;
import org.apache.hadoop.gateway.util.urltemplate.Resolver;
import org.apache.hadoop.gateway.util.urltemplate.Template;

import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriter.Direction.IN;
import static org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriter.Direction.OUT;

public class UrlRewriteProcessor implements UrlRewriter {

  private static final UrlRewriteMessages LOG = MessagesFactory.get( UrlRewriteMessages.class );

  UrlRewriteEnvironment environment;
  UrlRewriteRulesDescriptor descriptor;
  Map<String,UrlRewriteRuleProcessorHolder> rules = new HashMap<String,UrlRewriteRuleProcessorHolder>();
  ScopedMatcher inbound = new ScopedMatcher();
  ScopedMatcher outbound = new ScopedMatcher();
  Map<String,UrlRewriteFunctionProcessor> functions = new HashMap<String,UrlRewriteFunctionProcessor>();

  public UrlRewriteProcessor() {
  }

  // Convert the descriptor into processors.
  public void initialize( UrlRewriteEnvironment environment, UrlRewriteRulesDescriptor descriptor ) {
    this.environment = environment;
    this.descriptor = descriptor;
    initializeFunctions( descriptor );
    initializeRules( descriptor );
  }

  public UrlRewriteRulesDescriptor getConfig() {
    return descriptor;
  }

  @SuppressWarnings("unchecked")
  private void initializeFunctions( UrlRewriteRulesDescriptor rules ) {
    for( String name : UrlRewriteFunctionDescriptorFactory.getNames() ) {
      try {
        UrlRewriteFunctionDescriptor descriptor = rules.getFunction( name );
        UrlRewriteFunctionProcessor processor = UrlRewriteFunctionProcessorFactory.create( name, descriptor );
        processor.initialize( environment, descriptor );
        functions.put( name, processor );
      } catch( Exception e ) {
        // Ignore it and it won't be available as a function.
        LOG.failedToInitializeRewriteFunctions( e );
      }
    }
  }

  private void initializeRules( UrlRewriteRulesDescriptor descriptor ) {
    for( UrlRewriteRuleDescriptor ruleDescriptor : descriptor.getRules() ) {
      try {
        UrlRewriteRuleProcessorHolder ruleProcessor = new UrlRewriteRuleProcessorHolder();
        ruleProcessor.initialize( environment, ruleDescriptor );
        if( !rules.containsKey( ruleDescriptor.name() ) ) {
          rules.put( ruleDescriptor.name(), ruleProcessor );
        }
        Template template = ruleDescriptor.template();
        if( template != null ) {
          EnumSet<Direction> directions = ruleDescriptor.directions();
          if( directions == null || directions.isEmpty() ) {
            inbound.add( template, ruleProcessor );
            outbound.add( template, ruleProcessor );
          } else if( directions.contains( IN ) ) {
            inbound.add( template, ruleProcessor );
          } else if ( directions.contains( OUT ) ) {
            outbound.add( template, ruleProcessor );
          }
        }
      } catch( Exception e ) {
        LOG.failedToInitializeRewriteRules( e );
      }
    }
  }

  public void destroy() {
    for( UrlRewriteStepProcessorHolder rule : rules.values() ) {
      try {
        rule.destroy();
      } catch ( Exception e ) {
        LOG.failedToDestroyRewriteStepProcessor( e );
      }
    }
    for( UrlRewriteFunctionProcessor function : functions.values() ) {
      try {
        function.destroy();
      } catch( Exception e ) {
        LOG.failedToDestroyRewriteFunctionProcessor( e );
      }
    }
  }

  @Override
  public Template rewrite( Resolver resolver, Template inputUri, Direction direction, String ruleName ) {
    Template outputUri = inputUri;
    String serviceRole = null;
    if (resolver != null) {
      List<String> serviceRoles = resolver.resolve("service.role");
      if ( serviceRoles != null && !serviceRoles.isEmpty() ) {
        serviceRole = serviceRoles.get(0);
      }
    }
    UrlRewriteStepProcessorHolder stepHolder = null;
    String effectiveRuleName = null;
    if( ruleName == null || "*".equals( ruleName ) ) {
      ruleName = null; // Used for logging later.
      Matcher<UrlRewriteRuleProcessorHolder>.Match match = null;
      switch( direction ) {
        case IN:
          match = inbound.match( outputUri, serviceRole );
          break;
        case OUT:
          match = outbound.match( outputUri, serviceRole );
          break;
      }
      if( match != null ) {
        stepHolder = match.getValue();
        effectiveRuleName = match.getValue().getRuleName();
      }
    } else if( !ruleName.isEmpty() ) {
      stepHolder = rules.get( ruleName );
      effectiveRuleName = ruleName;
    }
    if( stepHolder != null ) {
      UrlRewriteContext context = new UrlRewriteContextImpl( environment, resolver, functions, direction, inputUri );
      try {
        UrlRewriteStepStatus stepStatus = stepHolder.process( context );
        if( UrlRewriteStepStatus.SUCCESS == stepStatus ) {
          outputUri = context.getCurrentUrl();
          if( ruleName == null ) {
            LOG.rewroteUrlViaImplicitRule( inputUri, direction, effectiveRuleName, outputUri );
          } else {
            LOG.rewroteUrlViaExplicitRule( inputUri, direction, effectiveRuleName, outputUri );
          }
        } else {
          LOG.failedToRewriteUrl( inputUri, direction, effectiveRuleName, stepStatus );
          outputUri = null;
        }
      } catch( Exception e ) {
        LOG.failedToRewriteUrlDueToException( inputUri, direction, effectiveRuleName, e );
        outputUri = null;
      }
    } else {
      LOG.noRuleMatchingUrl( inputUri, direction );
    }
    return outputUri;
  }

}
