/*
 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot.debugger.cdbg.basic;

import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.utilities.AddressOps;

public class BasicLineNumberMapping {
  private List infoList;

  public BasicLineNumberMapping() {
  }

  /** Add line number information for the given PC. The end PC may be
      a very loose approximation (i.e., the end of the given DLL) if
      that information is not available in the debug information.
      recomputeEndPCs() will recompute them if needed. */
  public void addLineNumberInfo(BasicLineNumberInfo info) {
    if (infoList == null) {
      infoList = new ArrayList();
    }
    infoList.add(info);
  }

  /** Sort the line number information by increasing starting program
      counter. This must be done before any queries are made. */
  public void sort() {
    if (infoList == null) return;
    Collections.sort(infoList, new Comparator() {
        public int compare(Object o1, Object o2) {
          BasicLineNumberInfo l1 = (BasicLineNumberInfo) o1;
          BasicLineNumberInfo l2 = (BasicLineNumberInfo) o2;
          Address a1 = l1.getStartPC();
          Address a2 = l2.getStartPC();
          if (AddressOps.lt(a1, a2)) { return -1; }
          if (AddressOps.gt(a1, a2)) { return 1; }
          return 0;
        }
      });
  }

  /** Recomputes the ending PCs of each interval based on the starting
      PC of the next one. If this needs to be called, must be called
      after sort(). */
  public void recomputeEndPCs() {
    if (infoList == null) return;
    for (int i = 0; i < infoList.size() - 1; i++) {
      BasicLineNumberInfo i1 = get(i);
      BasicLineNumberInfo i2 = get(i + 1);
      i1.setEndPC(i2.getStartPC());
    }
  }

  public BasicLineNumberInfo lineNumberForPC(Address pc) throws DebuggerException {
    if (infoList == null) return null;
    return searchLineNumbers(pc, 0, infoList.size() - 1);
  }

  public void iterate(LineNumberVisitor v) {
    if (infoList == null) return;
    for (int i = 0; i < infoList.size(); i++) {
      v.doLineNumber(get(i));
    }
  }

  //----------------------------------------------------------------------
  // Internals only below this point
  //

  private BasicLineNumberInfo get(int i) {
    return (BasicLineNumberInfo) infoList.get(i);
  }

  private BasicLineNumberInfo searchLineNumbers(Address addr, int lowIdx, int highIdx) {
    if (highIdx < lowIdx) return null;
    if (lowIdx == highIdx) {
      // Base case: see whether start PC is less than or equal to addr
      if (check(addr, lowIdx)) {
        return get(lowIdx);
      } else {
        return null;
      }
    } else if (lowIdx == highIdx - 1) {
      if (check(addr, lowIdx)) {
        return get(lowIdx);
      } else if (check(addr, highIdx)) {
        return get(highIdx);
      } else {
        return null;
      }
    }
    int midIdx = (lowIdx + highIdx) >> 1;
    BasicLineNumberInfo info = get(midIdx);
    if (AddressOps.lt(addr, info.getStartPC())) {
      // Always move search down
      return searchLineNumbers(addr, lowIdx, midIdx);
    } else if (AddressOps.equal(addr, info.getStartPC())) {
      return info;
    } else {
      // Move search up
      return searchLineNumbers(addr, midIdx, highIdx);
    }
  }

  private boolean check(Address addr, int idx) {
    BasicLineNumberInfo info = get(idx);
    if (AddressOps.lte(info.getStartPC(), addr)) {
      return true;
    } else {
      return false;
    }
  }
}
