/*
 * Copyright 2015 Cisco Systems, 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 com.cisco.oss.foundation.flowcontext;


import org.slf4j.MDC;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * This is the implementation of the FlowContext interface.
 * see <code>FlowContext</code>.
 * Any new members that added to this object MUST be transient in order to support backward compatibility
 *
 * @author Yair Ogen, Yehudit Glass
 */
final class FlowContextImpl implements FlowContext {

    /**
     *
     */
    private static final long serialVersionUID = -454792251461857981L;
    public static final String TX_DELIM = ".";
    private String uniqueId;
    private AtomicInteger innerTxCounter = new AtomicInteger(0);
    private boolean showTxCounter = false;

    /**
     * A constructor to generate FlowContextImpl object.
     */
    FlowContextImpl() {
        uniqueId = FlowContextGenerator.INSTANCE.getNextFlowContext();
        innerTxCounter.set(0);
    }

    /**
     * A constructor to generate FlowContextImpl object.
     * if uuid is null - generate uuid
     *
     * @param uuid
     */
    FlowContextImpl(final String uuid) {
        if (uuid == null) {
            uniqueId = "";
        } else {
            uniqueId = uuid.trim();
        }
    }

    /**
     * Convert a String to flowContext
     * if the String includes invalid pattern, default pattern is used
     *
     * @param flowContextString - String presenting flowComtext
     * @return FlowContext object
     */
    static FlowContext deserializeNativeFlowContext(final String flowContextString) { //NOPMD

        return new FlowContextImpl(flowContextString);
    }

//    void setInnerTxcouner(int counter) {
//        innerTxCounter.set(counter);
//        showTxCounter = true;
//    }

    void incrementInnerTxCounter() {
        innerTxCounter.incrementAndGet();
        showTxCounter = true;
        MDC.put("flowCtxt", toString());
    }

    void resetInnerTxCounter() {
        showTxCounter = false;
        MDC.put("flowCtxt", toString());
    }

    /**
     * Get String represent FlowContextImpl
     *
     * @return String that present the flowContextImpl.
     */
    synchronized String serializeNativeFlowContext() { //NOPMD
    	StringBuilder result = new StringBuilder(uniqueId);
        if (showTxCounter) {
            if (innerTxCounter.get() != 0) {
                result = result.append(TX_DELIM).append(innerTxCounter);
            }
        }
        return result.toString();
    }

    @Override
    public String toString() {

        final StringBuilder builder = new StringBuilder("[");
        builder.append(uniqueId);
        if (showTxCounter) {
            if (innerTxCounter.get() != 0) {
                builder.append(TX_DELIM).append(innerTxCounter);
            }
        }
        builder.append(']');
        return builder.toString();
    }

    /**
     * @return Unique Id generated by UUID
     */
    public String getUniqueId() {
        return uniqueId;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        FlowContextImpl other = (FlowContextImpl) obj;
        if (uniqueId == null) {
            if (other.uniqueId != null)
                return false;
        } else if (!uniqueId.equals(other.uniqueId))
            return false;
        return true;
    }


}

@@ -3154,11 +3154,8 @@
 der(
-%22%5B%22
 );%0A 
@@ -3354,37 +3354,8 @@
   %7D%0A
-        builder.append('%5D');%0A
     

update FC toString to support other logging conversion patterns that don't want the '[' and ']'