// -*- C++ -*-
//
// Copyright (C) 2009-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.

/** @file profile/impl/profiler_trace.h
 *  @brief Data structures to represent profiling traces.
 */

// Written by Lixia Liu and Silvius Rus.

#ifndef _GLIBCXX_PROFILE_PROFILER_TRACE_H
#define _GLIBCXX_PROFILE_PROFILER_TRACE_H 1

#include <cstdio>  // fopen, fclose, fprintf, FILE
#include <cerrno>
#include <cstdlib> // atof, atoi, strtol, getenv, atexit, abort

#if __cplusplus >= 201103L
#define _GLIBCXX_IMPL_UNORDERED_MAP std::_GLIBCXX_STD_C::unordered_map
#include <unordered_map>
#else
#include <tr1/unordered_map>
#define _GLIBCXX_IMPL_UNORDERED_MAP std::tr1::unordered_map
#endif

#include <ext/concurrence.h>
#include <fstream>
#include <string>
#include <utility>
#include <vector>

#include "profile/impl/profiler_algos.h"
#include "profile/impl/profiler_state.h"
#include "profile/impl/profiler_node.h"

namespace __gnu_profile
{
  /** @brief Internal environment.  Values can be set one of two ways:
      1. In config file "var = value".  The default config file path is 
         libstdcxx-profile.conf.
      2. By setting process environment variables.  For instance, in a Bash
         shell you can set the unit cost of iterating through a map like this:
         export __map_iterate_cost_factor=5.0.
	 If a value is set both in the input file and through an environment
	 variable, the environment value takes precedence.  */
  typedef _GLIBCXX_IMPL_UNORDERED_MAP<std::string, std::string> __env_t;

  _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__env_t, __env);

  /** @brief Master lock.  */
  _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__gnu_cxx::__mutex, __global_lock);

  /** @brief Representation of a warning.  */
  struct __warning_data
  {
    float __magnitude;
    __stack_t __context;
    const char* __warning_id;
    std::string __warning_message;

    __warning_data()
    : __magnitude(0.0), __context(0), __warning_id(0) { }

    __warning_data(float __m, __stack_t __c, const char* __id, 
		   const std::string& __msg)
    : __magnitude(__m), __context(__c), __warning_id(__id), 
      __warning_message(__msg) { }

    bool
    operator<(const __warning_data& __other) const
    { return __magnitude < __other.__magnitude; }
  };

  typedef std::_GLIBCXX_STD_C::vector<__warning_data> __warning_vector_t;

  // Defined in profiler_<diagnostic name>.h.
  class __trace_hash_func;
  class __trace_hashtable_size;
  class __trace_map2umap;
  class __trace_vector_size;
  class __trace_vector_to_list;
  class __trace_list_to_slist; 
  class __trace_list_to_vector; 
  void __trace_vector_size_init();
  void __trace_hashtable_size_init();
  void __trace_hash_func_init();
  void __trace_vector_to_list_init();
  void __trace_list_to_slist_init();  
  void __trace_list_to_vector_init();  
  void __trace_map_to_unordered_map_init();
  void __trace_vector_size_report(FILE*, __warning_vector_t&);
  void __trace_hashtable_size_report(FILE*, __warning_vector_t&);
  void __trace_hash_func_report(FILE*, __warning_vector_t&);
  void __trace_vector_to_list_report(FILE*, __warning_vector_t&);
  void __trace_list_to_slist_report(FILE*, __warning_vector_t&); 
  void __trace_list_to_vector_report(FILE*, __warning_vector_t&);
  void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&);

  struct __cost_factor
  {
    const char* __env_var;
    float __value;
  };

  typedef std::_GLIBCXX_STD_C::vector<__cost_factor*> __cost_factor_vector;

  _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, 0);
  _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, 0);
  _GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, 0);
  _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, 0);
  _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, 0);
  _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, 0); 
  _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, 0);

  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_shift_cost_factor, 
			       {"__vector_shift_cost_factor", 1.0});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_iterate_cost_factor,
			       {"__vector_iterate_cost_factor", 1.0});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_resize_cost_factor,
			       {"__vector_resize_cost_factor", 1.0}); 
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_shift_cost_factor,
			       {"__list_shift_cost_factor", 0.0});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_iterate_cost_factor,
			       {"__list_iterate_cost_factor", 10.0}); 
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_resize_cost_factor,
			       {"__list_resize_cost_factor", 0.0}); 
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_insert_cost_factor,
			       {"__map_insert_cost_factor", 1.5});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_erase_cost_factor,
			       {"__map_erase_cost_factor", 1.5});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_find_cost_factor,
			       {"__map_find_cost_factor", 1});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_iterate_cost_factor,
			       {"__map_iterate_cost_factor", 2.3});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_insert_cost_factor,
			       {"__umap_insert_cost_factor", 12.0});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_erase_cost_factor,
			       {"__umap_erase_cost_factor", 12.0});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_find_cost_factor,
			       {"__umap_find_cost_factor", 10.0});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_iterate_cost_factor,
			       {"__umap_iterate_cost_factor", 1.7});
  _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor_vector*, __cost_factors, 0);

  _GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name,
			       _GLIBCXX_PROFILE_TRACE_PATH_ROOT);
  _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_warn_count,
			       _GLIBCXX_PROFILE_MAX_WARN_COUNT);
  _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_stack_depth,
			       _GLIBCXX_PROFILE_MAX_STACK_DEPTH);
  _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_mem,
			       _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC);

  inline std::size_t
  __stack_max_depth()
  { return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth); }

  inline std::size_t
  __max_mem()
  { return _GLIBCXX_PROFILE_DATA(_S_max_mem); }

  /** @brief Base class for all trace producers.  */
  template<typename __object_info, typename __stack_info>
    class __trace_base
    {
    public:
      // Do not pick the initial size too large, as we don't know which
      // diagnostics are more active.
      __trace_base()
      : __object_table(10000), __stack_table(10000),
	__stack_table_byte_size(0), __id(0) { }

      virtual ~__trace_base() { }

      void __add_object(__object_t object, __object_info __info);
      __object_info* __get_object_info(__object_t __object);
      void __retire_object(__object_t __object);
      void __write(FILE* __f);
      void __collect_warnings(__warning_vector_t& __warnings);

    private:
      __gnu_cxx::__mutex __object_table_lock;
      __gnu_cxx::__mutex __stack_table_lock;
      typedef _GLIBCXX_IMPL_UNORDERED_MAP<__object_t, 
					  __object_info> __object_table_t;
      typedef _GLIBCXX_IMPL_UNORDERED_MAP<__stack_t, __stack_info,
					  __stack_hash, 
					  __stack_hash> __stack_table_t;
      __object_table_t __object_table;
      __stack_table_t __stack_table;
      std::size_t __stack_table_byte_size;

    protected:
      const char* __id;
    };

  template<typename __object_info, typename __stack_info>
    void
    __trace_base<__object_info, __stack_info>::
    __collect_warnings(__warning_vector_t& __warnings)
    {
      for (typename __stack_table_t::iterator __it
	     = __stack_table.begin(); __it != __stack_table.end(); ++__it)
	__warnings.push_back(__warning_data((*__it).second.__magnitude(),
					    (*__it).first, __id,
					    (*__it).second.__advice()));
    }

  template<typename __object_info, typename __stack_info>
    void
    __trace_base<__object_info, __stack_info>::
    __add_object(__object_t __object, __object_info __info)
    {
      if (__max_mem() == 0 
	  || __object_table.size() * sizeof(__object_info) <= __max_mem())
	{
	  this->__object_table_lock.lock();
	  __object_table.insert(typename __object_table_t::
				value_type(__object, __info));
	  this->__object_table_lock.unlock();
	}
    }

  template<typename __object_info, typename __stack_info>
    __object_info*
    __trace_base<__object_info, __stack_info>::
    __get_object_info(__object_t __object)
    {
      // XXX: Revisit this to see if we can decrease mutex spans.
      // Without this mutex, the object table could be rehashed during an
      // insertion on another thread, which could result in a segfault.
      this->__object_table_lock.lock();
      typename __object_table_t::iterator __object_it
	=  __object_table.find(__object);

      if (__object_it == __object_table.end())
	{
	  this->__object_table_lock.unlock();
	  return 0;
	}
      else
	{
	  this->__object_table_lock.unlock();
	  return &__object_it->second;
	}
    }

  template<typename __object_info, typename __stack_info>
    void
    __trace_base<__object_info, __stack_info>::
    __retire_object(__object_t __object)
    {
      this->__object_table_lock.lock();
      this->__stack_table_lock.lock();
      typename __object_table_t::iterator __object_it
	= __object_table.find(__object);
  
      if (__object_it != __object_table.end())
	{
	  const __object_info& __info = __object_it->second;
	  const __stack_t& __stack = __info.__stack();
	  typename __stack_table_t::iterator __stack_it
	    = __stack_table.find(__stack);
    
	  if (__stack_it == __stack_table.end())
	    {
	      // First occurrence of this call context.
	      if (__max_mem() == 0 || __stack_table_byte_size < __max_mem()) 
		{
		  __stack_table_byte_size 
		    += (sizeof(__instruction_address_t) * __size(__stack)
			+ sizeof(__stack) + sizeof(__stack_info));
		  __stack_table.insert(make_pair(__stack,
						 __stack_info(__info)));
		}
	    }
	  else
	    {
	      // Merge object info into info summary for this call context.
	      __stack_it->second.__merge(__info);
	      delete __stack;
	    }
	  __object_table.erase(__object);
	}

      this->__object_table_lock.unlock();
      this->__stack_table_lock.unlock();
    }

  template<typename __object_info, typename __stack_info>
    void
    __trace_base<__object_info, __stack_info>::
    __write(FILE* __f)
    {
      for (typename __stack_table_t::iterator __it
	     = __stack_table.begin(); __it != __stack_table.end(); ++__it)
	if (__it->second.__is_valid())
	  {
	    std::fprintf(__f, __id);
	    std::fprintf(__f, "|");
	    __gnu_profile::__write(__f, __it->first);
	    std::fprintf(__f, "|");
	    __it->second.__write(__f);
	  }
    }

  inline std::size_t
  __env_to_size_t(const char* __env_var, std::size_t __default_value)
  {
    char* __env_value = std::getenv(__env_var);
    if (__env_value)
      {
	errno = 0;
	long __converted_value = std::strtol(__env_value, 0, 10);
	if (errno || __converted_value < 0)
	  {
	    std::fprintf(stderr,
			 "Bad value for environment variable '%s'.\n",
			 __env_var);
	    std::abort();
	  }
	else
	  return static_cast<std::size_t>(__converted_value);
      }
    else
      return __default_value;
  }

  inline void
  __set_max_stack_trace_depth()
  {
    _GLIBCXX_PROFILE_DATA(_S_max_stack_depth)
      = __env_to_size_t(_GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR,
			_GLIBCXX_PROFILE_DATA(_S_max_stack_depth));
  }

  inline void
  __set_max_mem()
  {
    _GLIBCXX_PROFILE_DATA(_S_max_mem) 
      = __env_to_size_t(_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR,
			_GLIBCXX_PROFILE_DATA(_S_max_mem));
  }

  inline int
  __log_magnitude(float __f)
  {
    const float __log_base = 10.0;
    int __result = 0;
    int __sign = 1;

    if (__f < 0) 
      {
	__f = -__f;
	__sign = -1;
      }

    while (__f > __log_base) 
      {
	++__result;
	__f /= 10.0;
      }
    return __sign * __result;
  }

  inline FILE* 
  __open_output_file(const char* __extension)
  {
    // The path is made of _S_trace_file_name + "." + extension.
    std::size_t __root_len 
      = __builtin_strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
    std::size_t __ext_len = __builtin_strlen(__extension);
    char* __file_name = new char[__root_len + 1 + __ext_len + 1];
    __builtin_memcpy(__file_name,
		     _GLIBCXX_PROFILE_DATA(_S_trace_file_name),
		     __root_len);
    *(__file_name + __root_len) = '.';
    __builtin_memcpy(__file_name + __root_len + 1,
		     __extension, __ext_len + 1);

    FILE* __out_file = std::fopen(__file_name, "w");
    if (!__out_file)
      {
	std::fprintf(stderr, "Could not open trace file '%s'.\n",
		     __file_name);
	std::abort();
      }

    delete[] __file_name;
    return __out_file;
  }

  struct __warn
  {
    FILE* __file;

    __warn(FILE* __f)
    { __file = __f; }

    void
    operator()(const __warning_data& __info)
    {
      std::fprintf(__file,  __info.__warning_id);
      std::fprintf(__file, ": improvement = %d",
		   __log_magnitude(__info.__magnitude));
      std::fprintf(__file, ": call stack = ");
      __gnu_profile::__write(__file, __info.__context);
      std::fprintf(__file, ": advice = %s\n",
		   __info.__warning_message.c_str());
    }
  };

  /** @brief Final report method, registered with @b atexit.
   *
   * This can also be called directly by user code, including signal handlers.
   * It is protected against deadlocks by the reentrance guard in profiler.h.
   * However, when called from a signal handler that triggers while within
   * __gnu_profile (under the guarded zone), no output will be produced.
   */
  inline void
  __report(void)
  {
    _GLIBCXX_PROFILE_DATA(__global_lock).lock();

    __warning_vector_t __warnings, __top_warnings;

    FILE* __raw_file = __open_output_file("raw");
    __trace_vector_size_report(__raw_file, __warnings);
    __trace_hashtable_size_report(__raw_file, __warnings);
    __trace_hash_func_report(__raw_file, __warnings);
    __trace_vector_to_list_report(__raw_file, __warnings);
    __trace_list_to_slist_report(__raw_file, __warnings);
    __trace_list_to_vector_report(__raw_file, __warnings);
    __trace_map_to_unordered_map_report(__raw_file, __warnings);
    std::fclose(__raw_file);

    // Sort data by magnitude, keeping just top N.
    std::size_t __cutoff = std::min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count),
				    __warnings.size());
    __top_n(__warnings, __top_warnings, __cutoff);

    FILE* __warn_file = __open_output_file("txt");
    __for_each(__top_warnings.begin(), __top_warnings.end(),
	       __warn(__warn_file));
    std::fclose(__warn_file);

    _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
  }

  inline void
  __set_trace_path()
  {
    char* __env_trace_file_name = std::getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);

    if (__env_trace_file_name)
      _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name;

    // Make sure early that we can create the trace file.
    std::fclose(__open_output_file("txt"));
  }

  inline void
  __set_max_warn_count()
  {
    char* __env_max_warn_count_str
      = std::getenv(_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);

    if (__env_max_warn_count_str)
      _GLIBCXX_PROFILE_DATA(_S_max_warn_count)
	= static_cast<std::size_t>(std::atoi(__env_max_warn_count_str));
  }

  inline void
  __read_cost_factors()
  {
    std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
    __conf_file_name += ".conf";

    std::ifstream __conf_file(__conf_file_name.c_str());

    if (__conf_file.is_open())
      {
	std::string __line;

	while (std::getline(__conf_file, __line))
	  {
	    std::string::size_type __i = __line.find_first_not_of(" \t\n\v");

	    if (__line.length() <= 0 || __line[__i] == '#')
	      // Skip empty lines or comments.
	      continue;
	  }

	// Trim.
	__line.erase(__remove(__line.begin(), __line.end(), ' '),
		     __line.end());
	std::string::size_type __pos = __line.find("=");
	std::string __factor_name = __line.substr(0, __pos);
	std::string::size_type __end = __line.find_first_of(";\n");
	std::string __factor_value = __line.substr(__pos + 1, __end - __pos);

	_GLIBCXX_PROFILE_DATA(__env)[__factor_name] = __factor_value;
      }
  }

  struct __cost_factor_writer
  {
    FILE* __file;

    __cost_factor_writer(FILE* __f)
    : __file(__f) { }

    void
    operator() (const __cost_factor* __factor)
    { std::fprintf(__file, "%s = %f\n", __factor->__env_var,
		   __factor->__value); }
  };

  inline void
  __write_cost_factors()
  {
    FILE* __file = __open_output_file("conf.out");
    __for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
	       _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
	       __cost_factor_writer(__file));
    std::fclose(__file);
  }

  struct __cost_factor_setter
  {
    void
    operator()(__cost_factor* __factor)
    {
      // Look it up in the process environment first.
      const char* __env_value = std::getenv(__factor->__env_var);

      if (!__env_value)
        {
          // Look it up in the config file.
          __env_t::iterator __it 
	    = _GLIBCXX_PROFILE_DATA(__env).find(__factor->__env_var);
          if (__it != _GLIBCXX_PROFILE_DATA(__env).end())
            __env_value = (*__it).second.c_str();
        }

      if (__env_value)
        __factor->__value = std::atof(__env_value);
    }
  };

  inline void
  __set_cost_factors()
  {
    _GLIBCXX_PROFILE_DATA(__cost_factors) = new __cost_factor_vector;
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__list_shift_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__list_resize_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__map_find_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__umap_find_cost_factor));
    _GLIBCXX_PROFILE_DATA(__cost_factors)->
      push_back(&_GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor));
    __for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
	       _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
	       __cost_factor_setter());
  }

  inline void
  __profcxx_init_unconditional()
  {
    _GLIBCXX_PROFILE_DATA(__global_lock).lock();

    if (__is_invalid())
      {
	__set_max_warn_count();

	if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0)
	  __turn_off();
	else
	  {
	    __set_max_stack_trace_depth();
	    __set_max_mem();
	    __set_trace_path();
	    __read_cost_factors(); 
	    __set_cost_factors();
	    __write_cost_factors();

	    __trace_vector_size_init();
	    __trace_hashtable_size_init();
	    __trace_hash_func_init();
	    __trace_vector_to_list_init();
	    __trace_list_to_slist_init(); 
	    __trace_list_to_vector_init();
	    __trace_map_to_unordered_map_init();

	    std::atexit(__report);

	    __turn_on();
	  }
      }

    _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
  }

  /** @brief This function must be called by each instrumentation point.
   *
   * The common path is inlined fully.
   */
  inline bool
  __profcxx_init()
  {
    if (__is_invalid())
      __profcxx_init_unconditional();

    return __is_on();
  }

} // namespace __gnu_profile

#endif /* _GLIBCXX_PROFILE_PROFILER_TRACE_H */
