/*
 * 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.
 */

#include <log4cxx/spi/location/locationinfo.h>
#include <log4cxx/helpers/objectoutputstream.h>
#include <log4cxx/helpers/pool.h>
#include "apr_pools.h"
#include "apr_strings.h"

using namespace ::log4cxx::spi;
using namespace log4cxx::helpers;

/**
  When location information is not available the constant
  <code>NA</code> is returned. Current value of this string
  constant is <b>?</b>.  */
const char* const LocationInfo::NA = "?";
const char* const LocationInfo::NA_METHOD = "?::?";

const LocationInfo& LocationInfo::getLocationUnavailable()
{
    static const LocationInfo unavailable;
    return unavailable;
}

/**
*   Constructor.
*   @remarks Used by LOG4CXX_LOCATION to generate
*       location info for current code site
*/
LocationInfo::LocationInfo( const char* const fileName1,
                            const char* const methodName1,
                            int lineNumber1 )
    :  lineNumber( lineNumber1 ),
       fileName( fileName1 ),
       methodName( methodName1 )
{
}

/**
*   Default constructor.
*/
LocationInfo::LocationInfo()
    : lineNumber( -1 ),
      fileName(LocationInfo::NA),
      methodName(LocationInfo::NA_METHOD)
{
}

/**
*   Copy constructor.
*   @param src source location
*/
LocationInfo::LocationInfo( const LocationInfo& src )
    :  lineNumber( src.lineNumber ),
       fileName( src.fileName ),
       methodName( src.methodName )
{
}

/**
*  Assignment operator.
* @param src source location
*/
LocationInfo& LocationInfo::operator = ( const LocationInfo& src )
{
    fileName = src.fileName;
    methodName = src.methodName;
    lineNumber = src.lineNumber;
    return * this;
}

/**
 *   Resets location info to default state.
 */
void LocationInfo::clear()
{
    fileName = NA;
    methodName = NA_METHOD;
    lineNumber = -1;
}


/**
 *   Return the file name of the caller.
 *   @returns file name, may be null.
 */
const char* LocationInfo::getFileName() const
{
    return fileName;
}

/**
  *   Returns the line number of the caller.
  * @returns line number, -1 if not available.
  */
int LocationInfo::getLineNumber() const
{
    return lineNumber;
}

/** Returns the method name of the caller. */
const std::string LocationInfo::getMethodName() const
{
    std::string tmp(methodName);
    size_t parenPos = tmp.find('(');

    if (parenPos != std::string::npos)
    {
        tmp.erase(parenPos);
    }

    size_t colonPos = tmp.rfind("::");

    if (colonPos != std::string::npos)
    {
        tmp.erase(0, colonPos + 2);
    }
    else
    {
        size_t spacePos = tmp.find(' ');

        if (spacePos != std::string::npos)
        {
            tmp.erase(0, spacePos + 1);
        }
    }

    return tmp;
}


const std::string LocationInfo::getClassName() const
{
    std::string tmp(methodName);
    size_t parenPos = tmp.find('(');

    if (parenPos != std::string::npos)
    {
        tmp.erase(parenPos);
    }

    size_t colonPos = tmp.rfind("::");

    if (colonPos != std::string::npos)
    {
        tmp.erase(colonPos);
        size_t spacePos = tmp.find_last_of(' ');

        if (spacePos != std::string::npos)
        {
            tmp.erase(0, spacePos + 1);
        }

        return tmp;
    }

    tmp.erase(0, tmp.length() );
    return tmp;
}

void LocationInfo::write(ObjectOutputStream& os, Pool& p) const
{
    if (lineNumber == -1 && fileName == NA && methodName == NA_METHOD)
    {
        os.writeNull(p);
    }
    else
    {
        unsigned char prolog[] =
        {
            0x72,
            0x00,
            0x21, 0x6F, 0x72, 0x67, 0x2E, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2E,
            0x6C, 0x6F, 0x67, 0x34, 0x6A, 0x2E, 0x73, 0x70, 0x69, 0x2E, 0x4C, 0x6F,
            0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x6E, 0x66, 0x6F, 0xED, 0x99,
            0xBB, 0xE1, 0x4A, 0x91, 0xA5, 0x7C, 0x02,
            0x00,
            0x01, 0x4C,
            0x00,
            0x08, 0x66, 0x75, 0x6C, 0x6C, 0x49, 0x6E, 0x66, 0x6F, 0x74,
            0x00,
            0x12, 0x4C, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F,
            0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 0x78, 0x70
        };
        os.writeProlog("org.apache.log4j.spi.LocationInfo", 2, (char*) prolog, sizeof(prolog), p);
        char* line = p.itoa(lineNumber);
        //
        //   construct Java-like fullInfo (replace "::" with ".")
        //
        std::string fullInfo(methodName);
        size_t openParen = fullInfo.find('(');

        if (openParen != std::string::npos)
        {
            size_t space = fullInfo.find(' ');

            if (space != std::string::npos && space < openParen)
            {
                fullInfo.erase(0, space + 1);
            }
        }

        openParen = fullInfo.find('(');

        if (openParen != std::string::npos)
        {
            size_t classSep = fullInfo.rfind("::", openParen);

            if (classSep != std::string::npos)
            {
                fullInfo.replace(classSep, 2, ".");
            }
            else
            {
                fullInfo.insert(0, ".");
            }
        }

        fullInfo.append(1, '(');
        fullInfo.append(fileName);
        fullInfo.append(1, ':');
        fullInfo.append(line);
        fullInfo.append(1, ')');
        os.writeUTFString(fullInfo, p);
    }
}


