/*
 * Copyright (c) 2004 - 2012 Eike Stepper (Loehne, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package promoter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import promoter.util.IO;

/**
 * @author Eike Stepper
 */
public class Bugzilla extends IssueManager
{
  public static final String SERVER = "https://bugs.eclipse.org/";

  public static final String XML = SERVER + "bugs/show_bug.cgi?ctype=xml&id=";

  private static final int RETRIES = 3;

  public Bugzilla()
  {
  }

  @Override
  public String parseID(String message)
  {
    if (message.length() >= 3 && message.charAt(0) == '[')
    {
      int end = message.indexOf(']');
      if (end != -1)
      {
        String id = message.substring(1, end);

        try
        {
          Integer.parseInt(id); // Valid integer?
          return id;
        }
        catch (NumberFormatException ex)
        {
          //$FALL-THROUGH$
        }
      }
    }

    return "";
  }

  @Override
  protected Issue doGetIssue(String id)
  {
    for (int i = 0; i < RETRIES; i++)
    {
      try
      {
        BugHandler handler = new BugHandler();
        IO.readURL(XML + id, handler);
        return handler.getIssue();
      }
      catch (Exception ex)
      {
        if (i == RETRIES - 1)
        {
          throw new RuntimeException(ex);
        }
      }
    }

    return null;
  }

  @Override
  public String getURL(Issue issue)
  {
    return SERVER + issue.getID();
  }

  @Override
  public Integer getSeverity(Issue issue)
  {
    String severity = issue.getSeverity();
    if ("trivial".equals(severity))
    {
      return 1;
    }

    if ("minor".equals(severity))
    {
      return 2;
    }

    if ("normal".equals(severity))
    {
      return 3;
    }

    if ("major".equals(severity))
    {
      return 4;
    }

    if ("critical".equals(severity))
    {
      return 5;
    }

    if ("blocker".equals(severity))
    {
      return 6;
    }

    return 0;
  }

  @Override
  public int compare(Issue i1, Issue i2)
  {
    return Integer.valueOf(i1.getID()).compareTo(Integer.valueOf(i2.getID()));
  }

  public static void main(String[] args)
  {
    Issue issue = new Bugzilla().doGetIssue("355921");
    System.out.println(issue.getTitle());
    System.out.println(issue.getSeverity());
  }

  /**
   * @author Eike Stepper
   */
  private static final class BugHandler implements IO.InputHandler
  {
    private Issue issue;

    public BugHandler()
    {
    }

    public final Issue getIssue()
    {
      return issue;
    }

    @Override
    public void handleInput(InputStream in) throws IOException
    {
      String id = null;
      String title = null;
      String severity = null;
      String component = null;
      String version = null;
      String status = null;
      String resolution = null;

      BufferedReader reader = new BufferedReader(new InputStreamReader(in));
      String line;
      while ((line = reader.readLine()) != null)
      {
        line = line.trim();

        if (id == null)
        {
          id = match(line, "bug_id");
        }

        if (title == null)
        {
          title = match(line, "short_desc");
        }

        if (severity == null)
        {
          severity = match(line, "bug_severity");
        }

        if (component == null)
        {
          component = match(line, "component");
        }

        if (version == null)
        {
          version = match(line, "version");
        }

        if (status == null)
        {
          status = match(line, "bug_status");
        }

        if (resolution == null)
        {
          if ("<resolution/>".equals(line))
          {
            resolution = "";
          }
          else
          {
            resolution = match(line, "resolution");
          }
        }

        if (id != null && title != null && severity != null && component != null && version != null && status != null && resolution != null)
        {
          if (resolution.length() != 0)
          {
            status += "-" + resolution.toLowerCase();
          }

          issue = new Issue(id, title, severity, component, version, status);
          break;
        }
      }
    }

    private String match(String line, String element)
    {
      String start = "<" + element + ">";
      if (line.startsWith(start))
      {
        line = line.substring(start.length());

        String end = "</" + element + ">";
        if (line.endsWith(end))
        {
          return line.substring(0, line.length() - end.length());
        }
      }

      return null;
    }
  }
}
