/*
 * Copyright (C) 2012 Red Hat, Inc.
 *
 * Licensed 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.commonjava.maven.ext.core.state;

import org.apache.commons.lang.StringUtils;
import org.commonjava.maven.ext.annotation.ConfigValue;
import org.commonjava.maven.ext.core.ManipulationSession;
import org.commonjava.maven.ext.core.impl.DependencyManipulator;
import org.commonjava.maven.ext.io.rest.DefaultTranslator;
import org.commonjava.maven.ext.io.rest.Translator;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * Captures configuration relating to dependency alignment from the POMs. Used by {@link DependencyManipulator}.
 */
public class RESTState implements State
{
    @ConfigValue( docIndex = "dep-manip.html#rest-endpoint" )
    public static final String REST_URL = "restURL";

    @ConfigValue( docIndex = "dep-manip.html#rest-endpoint" )
    public static final String REST_REPO_GROUP = "restRepositoryGroup";

    @ConfigValue( docIndex = "dep-manip.html#rest-endpoint" )
    public static final String REST_MAX_SIZE = "restMaxSize";

    @ConfigValue( docIndex = "dep-manip.html#rest-endpoint" )
    public static final String REST_MIN_SIZE = "restMinSize";

    @ConfigValue( docIndex = "dep-manip.html#rest-endpoint" )
    public static final String REST_SUFFIX = "restSuffixAlign";

    @ConfigValue( docIndex = "dep-manip.html#rest-endpoint" )
    public static final String REST_HEADERS = "restHeaders";

    @ConfigValue( docIndex = "dep-manip.html#rest-timeouts-and-retries" )
    public static final String REST_CONNECTION_TIMEOUT_SEC = "connectionTimeout";

    @ConfigValue( docIndex = "dep-manip.html#rest-timeouts-and-retries" )
    public static final String REST_SOCKET_TIMEOUT_SEC = "socketTimeout";

    @ConfigValue( docIndex = "dep-manip.html#rest-timeouts-and-retries" )
    public static final String REST_RETRY_DURATION_SEC = "retryTimeout";

    private final ManipulationSession session;

    private String restURL;

    private Translator restEndpoint;

    private boolean restSuffixAlign;

    private Map<String, String> restHeaders;

    private int connectionTimeout;

    private int socketTimeout;

    private int retryTimeout;

    public RESTState( final ManipulationSession session )
    {
        this.session = session;

        initialise( session.getUserProperties() );
    }

    public void initialise( Properties userProps )
    {
        final VersioningState vState = session.getState( VersioningState.class );

        restURL = userProps.getProperty( REST_URL );

        String repositoryGroup = userProps.getProperty( REST_REPO_GROUP, "" );
        int restMaxSize = Integer.parseInt( userProps.getProperty( REST_MAX_SIZE, "-1" ) );
        int restMinSize = Integer.parseInt( userProps.getProperty( REST_MIN_SIZE,
                                                                   String.valueOf( DefaultTranslator.CHUNK_SPLIT_COUNT ) ) );
        restSuffixAlign = Boolean.parseBoolean( userProps.getProperty( REST_SUFFIX, "true" ) );

        String restHeadersProperty = userProps.getProperty( REST_HEADERS, "" );
        if ( !StringUtils.isEmpty( restHeadersProperty ) )
        {
            restHeaders = Arrays.stream( restHeadersProperty.split( "," ) )
                                .map( h -> h.split( ":", 2 ) )
                                .filter( h -> h.length > 0 && StringUtils.isNotEmpty( h[0] ) )
                                .collect( Collectors.toMap( h -> h[0], h -> h.length > 1 ? h[1] : "",
                                                            ( x, y ) -> y, LinkedHashMap::new ) );
        }

        connectionTimeout = Integer.parseInt( userProps.getProperty( REST_CONNECTION_TIMEOUT_SEC, String.valueOf( DefaultTranslator.DEFAULT_CONNECTION_TIMEOUT_SEC ) ) );
        socketTimeout = Integer.parseInt( userProps.getProperty( REST_SOCKET_TIMEOUT_SEC, String.valueOf( DefaultTranslator.DEFAULT_SOCKET_TIMEOUT_SEC ) ) );
        retryTimeout = Integer.parseInt( userProps.getProperty( REST_RETRY_DURATION_SEC, String.valueOf( DefaultTranslator.RETRY_DURATION_SEC ) ) );

        restEndpoint = new DefaultTranslator( restURL, restMaxSize, restMinSize, repositoryGroup, vState.getIncrementalSerialSuffix(), restHeaders,
                                              connectionTimeout, socketTimeout, retryTimeout);
    }

    /**
     * Enabled ONLY if propertyManagement is provided in the user properties / CLI -D options.
     *
     * @see State#isEnabled()
     */
    @Override
    public boolean isEnabled()
    {
        return restURL != null && !restURL.isEmpty();
    }

    public Translator getVersionTranslator()
    {
        return restEndpoint;
    }

    public boolean isRestSuffixAlign()
    {
        return restSuffixAlign;
    }
}

@@ -2175,17 +2175,21 @@
 _SEC = %22
-c
+restC
 onnectio
@@ -2332,17 +2332,21 @@
 _SEC = %22
-s
+restS
 ocketTim
@@ -2487,26 +2487,31 @@
 EC = %22re
-tryTimeout
+stRetryDuration
 %22;%0A%0A    
@@ -2721,17 +2721,21 @@
 ate int 
-c
+restC
 onnectio
@@ -2761,17 +2761,21 @@
 ate int 
-s
+restS
 ocketTim
@@ -2799,26 +2799,31 @@
 e int re
-tryTimeout
+stRetryDuration
 ;%0A%0A    p
@@ -4237,33 +4237,37 @@
      %7D%0A%0A        
-c
+restC
 onnectionTimeout
@@ -4419,17 +4419,21 @@
         
-s
+restS
 ocketTim
@@ -4583,26 +4583,31 @@
       re
-tryTimeout
+stRetryDuration
  = Integ
@@ -4922,17 +4922,21 @@
         
-c
+restC
 onnectio
@@ -4945,17 +4945,21 @@
 imeout, 
-s
+restS
 ocketTim
@@ -4970,18 +4970,23 @@
 , re
-tryTimeout
+stRetryDuration
 );%0A 

Refactor properties with prefix rest