/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed 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.
 */
package com.google.gwt.uibinder.rebind;

import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.resource.ResourceOracle;
import com.google.gwt.dev.util.Util;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.uibinder.rebind.messages.MessagesWriter;
import com.google.gwt.uibinder.rebind.model.ImplicitClientBundle;

import org.w3c.dom.Document;
import org.xml.sax.SAXParseException;

import java.io.PrintWriter;

/**
 * Generator for implementations of
 * {@link com.google.gwt.uibinder.client.UiBinder}.
 */
public class UiBinderGenerator extends Generator {

  private static final String TEMPLATE_SUFFIX = ".ui.xml";

  static final String BINDER_URI = "urn:ui:com.google.gwt.uibinder";

  /**
   * Given a UiBinder interface, return the path to its ui.xml file, suitable
   * for any classloader to find it as a resource.
   */
  private static String deduceTemplateFile(MortalLogger logger,
      JClassType interfaceType) throws UnableToCompleteException {
    String templateName = null;
    UiTemplate annotation = interfaceType.getAnnotation(UiTemplate.class);
    if (annotation == null) {
      // if the interface is defined as a nested class, use the name of the
      // enclosing type
      if (interfaceType.getEnclosingType() != null) {
        interfaceType = interfaceType.getEnclosingType();
      }
      return slashify(interfaceType.getQualifiedSourceName()) + TEMPLATE_SUFFIX;
    } else {
      templateName = annotation.value();
      if (!templateName.endsWith(TEMPLATE_SUFFIX)) {
        logger.die("Template file name must end with " + TEMPLATE_SUFFIX);
      }

      /*
       * If the template file name (minus suffix) has no dots, make it relative
       * to the binder's package, otherwise slashify the dots
       */
      String unsuffixed = templateName.substring(0,
          templateName.lastIndexOf(TEMPLATE_SUFFIX));
      if (!unsuffixed.contains(".")) {
        templateName = slashify(interfaceType.getPackage().getName()) + "/"
            + templateName;
      } else {
        templateName = slashify(unsuffixed) + TEMPLATE_SUFFIX;
      }
    }
    return templateName;
  }

  private static String slashify(String s) {
    return s.replace(".", "/");
  }

  private final UiBinderContext uiBinderCtx = new UiBinderContext();

  @Override
  public String generate(TreeLogger logger, GeneratorContext genCtx,
      String fqInterfaceName) throws UnableToCompleteException {
    TypeOracle oracle = genCtx.getTypeOracle();
    ResourceOracle resourceOracle = genCtx.getResourcesOracle();

    JClassType interfaceType;
    try {
      interfaceType = oracle.getType(fqInterfaceName);
    } catch (NotFoundException e) {
      throw new RuntimeException(e);
    }

    DesignTimeUtils designTime;
    if (DesignTimeUtilsImpl.isDesignTime(fqInterfaceName)) {
      designTime = new DesignTimeUtilsImpl();
    } else {
      designTime = DesignTimeUtilsStub.EMPTY;
    }

    String implName = interfaceType.getName().replace('.', '_') + "Impl";
    implName = designTime.getImplName(implName);

    String packageName = interfaceType.getPackage().getName();
    PrintWriterManager writers = new PrintWriterManager(genCtx, logger,
        packageName);
    PrintWriter printWriter = writers.tryToMakePrintWriterFor(implName);

    if (printWriter != null) {
      generateOnce(interfaceType, implName, printWriter, logger, oracle,
          resourceOracle, writers, designTime);
    }
    return packageName + "." + implName;
  }

  private void generateOnce(JClassType interfaceType, String implName,
      PrintWriter binderPrintWriter, TreeLogger treeLogger, TypeOracle oracle,
      ResourceOracle resourceOracle, PrintWriterManager writerManager,
      DesignTimeUtils designTime) throws UnableToCompleteException {

    MortalLogger logger = new MortalLogger(treeLogger);
    String templatePath = deduceTemplateFile(logger, interfaceType);
    MessagesWriter messages = new MessagesWriter(BINDER_URI, logger,
        templatePath, interfaceType.getPackage().getName(), implName);

    UiBinderWriter uiBinderWriter = new UiBinderWriter(interfaceType, implName,
        templatePath, oracle, logger, new FieldManager(oracle, logger),
        messages, designTime, uiBinderCtx);

    Document doc = getW3cDoc(logger, designTime, resourceOracle, templatePath);
    designTime.rememberPathForElements(doc);

    uiBinderWriter.parseDocument(doc, binderPrintWriter);

    if (messages.hasMessages()) {
      messages.write(writerManager.makePrintWriterFor(messages.getMessagesClassName()));
    }

    ImplicitClientBundle bundleClass = uiBinderWriter.getBundleClass();
    new BundleWriter(bundleClass, writerManager, oracle, logger).write();

    writerManager.commit();
  }

  private Document getW3cDoc(MortalLogger logger, DesignTimeUtils designTime,
      ResourceOracle resourceOracle, String templatePath)
      throws UnableToCompleteException {

    Resource resource = resourceOracle.getResourceMap().get(templatePath);
    if (null == resource) {
      logger.die("Unable to find resource: " + templatePath);
    }

    Document doc = null;
    try {
      String content = designTime.getTemplateContent(templatePath);
      if (content == null) {
        content = Util.readStreamAsString(resource.openContents());
      }
      doc = new W3cDomHelper(logger.getTreeLogger(), resourceOracle).documentFor(
          content, resource.getPath());
    } catch (SAXParseException e) {
      logger.die(
          "Error parsing XML (line " + e.getLineNumber() + "): "
              + e.getMessage(), e);
    }
    return doc;
  }
}
