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


var get_tooltip = function( segment_response ) {
    var tooltip =
        '<div>Segment <b>' + segment_response.name + '</b>:</div>' +
        '<div class="label">#docs:</div><div>' + number_format(segment_response.size) +'</div>' +
        '<div class="label">#dels:</div><div>' + number_format(segment_response.delCount) + '</div>' +
        '<div class="label">size:</div><div>' + number_format(segment_response.sizeInBytes) + ' bytes </div>' +
        '<div class="label">age:</div><div>' + segment_response.age + '</div>' +
        '<div class="label">source:</div><div>' + segment_response.source + '</div>';
    return tooltip;
};

var get_entry = function( segment_response, segment_bytes_max ) {
    //calcualte dimensions of graph
    var dims = calculate_dimensions(segment_response.sizeInBytes, 
            segment_bytes_max, segment_response.size, segment_response.delCount)
    //create entry for segment with given dimensions
    var entry = get_entry_item(segment_response.name, dims, 
            get_tooltip(segment_response), (segment_response.mergeCandidate)?true:false);

    return entry;
};

var get_entry_item = function(name, dims, tooltip, isMergeCandidate) {
    var entry = '<li>' + "\n" +
    '  <dl class="clearfix" style="width: ' + dims['size'] + '%;">' + "\n" +
    '    <dt><div>' + name + '</div></dt>' + "\n" +
    '    <dd>';
    entry += '<div class="live' + ((isMergeCandidate)?' merge-candidate':'') + 
         '" style="width: ' + dims['alive_doc_size'] + '%;">&nbsp;</div>';
    entry += '<div class="toolitp">' + tooltip +'</div>';
      
    if (dims['deleted_doc_size'] > 0.001) {
     entry += '<div class="deleted" style="width:' + dims['deleted_doc_size']  
         + '%;margin-left:' + dims['alive_doc_size'] + '%;">&nbsp;</div>';
    }
    entry += '</dd></dl></li>';
    return entry;
};

var get_footer = function(deletions_count, documents_count) {
    return '<li><dl><dt></dt><dd>Deletions: ' + 
        (documents_count == 0 ? 0 : round_2(deletions_count/documents_count * 100)) +
            '% </dd></dl></li>';
};

var calculate_dimensions = function(segment_size_in_bytes, segment_size_in_bytes_max, doc_count, delete_doc_count) {
    var segment_size_in_bytes_log = Math.log(segment_size_in_bytes);
    var segment_size_in_bytes_max_log = Math.log(segment_size_in_bytes_max);

    var dims = {};
    //Normalize to 100% size of bar
    dims['size'] = Math.floor((segment_size_in_bytes_log / segment_size_in_bytes_max_log ) * 100);
    //Deleted doc part size
    dims['deleted_doc_size'] = Math.floor((delete_doc_count/(delete_doc_count + doc_count)) * dims['size']);
    //Alive doc part size
    dims['alive_doc_size'] = dims['size'] - dims['deleted_doc_size'];

    return dims;
};

var calculate_max_size_on_disk = function(segment_entries) {
    var max = 0;
    $.each(segment_entries, function(idx, obj) {
        if (obj.sizeInBytes > max) {
            max = obj.sizeInBytes;
        }
    });
    return max;
};

var round_2 = function(num) {
    return Math.round(num*100)/100;
};

var number_format = function(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
};

var prepare_x_axis = function(segment_bytes_max) {
    var factor = 1024*1024; //for MB
    
    var segment_bytes_max_log = Math.log(segment_bytes_max);
    
    var series_entry = '<li>' + "\n" +
    '  <dl class="clearfix" style="width:100%;">' + "\n" +
    '    <dt><div>Size</div></dt>' + "\n" +
    '    <dd>' + 
    '        <div class="start">0</div>';
    var step = 0;
    for (var j = 0; j < 3; j+=1) {
            step += segment_bytes_max_log/4;
            var step_value = number_format(Math.floor((Math.pow(Math.E, step))/factor))
            series_entry += '<div class="w5">' + ((step_value > 0.001)?step_value : '&nbsp;')  + '</div>'
    }
    series_entry += '<div class="end">' + number_format(Math.floor(segment_bytes_max/factor)) + ' MB </div>' +
    '    </dd>' +
    '  </dl>' +
    '</li>';
    return series_entry;
};

// #/:core/admin/segments
sammy.get
(
  new RegExp( app.core_regex_base + '\\/(segments)$' ),
  function( context )
  {
    var core_basepath = this.active_core.attr( 'data-basepath' );
    var content_element = $( '#content' );
        
    $.get
    (
      'tpl/segments.html',
      function( template )
      {
        content_element.html( template );
            
        var segments_element = $('#segments', content_element);
        var segments_reload = $( '#segments a.reload' );
        var url_element = $('#url', segments_element);
        var result_element = $('#result', segments_element);
        var response_element = $('#response', result_element);
        var segments_holder_element = $('.segments-holder', result_element);

        segments_reload
            .die( 'click' )
            .live
            (
            'click',
            function( event )
            {
                $.ajax
                (
                  {
                    url : core_basepath +  '/admin/segments?wt=json',
                    dataType : 'json',
                    context: this,
                    beforeSend : function( arr, form, options )
                    {
                      loader.show( this );    
                    },
                    success : function( response, text_status, xhr )
                    {
                        var segments_response = response['segments'],
                            segments_entries = [],
                            segment_bytes_max = calculate_max_size_on_disk( segments_response );

                        //scale
                        segments_entries.push( prepare_x_axis( segment_bytes_max ) );
                        
                        var documents_count = 0, deletions_count = 0;
                        
                        //elements
                        $.each( segments_response, function( key, segment_response ) {
                            segments_entries.push( get_entry( segment_response, segment_bytes_max ) );
                            
                            documents_count += segment_response.size;
                           deletions_count += segment_response.delCount;
                        });
     
                        //footer
                        segments_entries.push( get_footer( deletions_count, documents_count ) );
                        
                        $( 'ul', segments_holder_element ).html( segments_entries.join("\n" ) );
                    },
                    error : function( xhr, text_status, error_thrown )
                    {
                      $( this )
                        .attr( 'title', '/admin/segments is not configured (' + xhr.status + ': ' + error_thrown + ')' );

                      $( this ).parents( 'li' )
                        .addClass( 'error' );
                    },
                    complete : function( xhr, text_status )
                    {
                      loader.hide( this );
                    }
                  }
                );
              return false;
            }
          );
        //initially submit
        segments_reload.click();
      }
    );
  }
);
