/*
 * Copyright 2009 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.model;

import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.resources.css.ExtractClassNamesVisitor;
import com.google.gwt.resources.css.GenerateCssAst;
import com.google.gwt.resources.css.ast.CssStylesheet;
import com.google.gwt.resources.ext.ResourceGeneratorUtil;
import com.google.gwt.uibinder.attributeparsers.CssNameConverter;
import com.google.gwt.uibinder.rebind.MortalLogger;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Models a method returning a CssResource on a generated ClientBundle.
 */
public class ImplicitCssResource {
  private static final CssNameConverter nameConverter = new CssNameConverter();
  private final String packageName;
  private final String className;
  private final String name;
  private final List<String> sources;
  private final JClassType extendedInterface;
  private final String body;
  private final MortalLogger logger;
  private final Set<JClassType> imports;

  private File generatedFile;
  private Set<String> cssClassNames;
  private Set<String> normalizedCssClassNames;

  /**
   * Visible for testing only, get instances from {@link ImplicitClientBundle}.
   */
  public ImplicitCssResource(String packageName, String className, String name,
      String[] source, JClassType extendedInterface, String body,
      MortalLogger logger, Set<JClassType> importTypes) {
    this.packageName = packageName;
    this.className = className;
    this.name = name;
    this.extendedInterface = extendedInterface;
    this.body = body;
    this.logger = logger;
    this.imports = Collections.unmodifiableSet(importTypes);
    sources = Arrays.asList(source);
  }

  /**
   * @return the name of the CssResource interface
   */
  public String getClassName() {
    return className;
  }

  /**
   * @return the set of CSS classnames in the underlying .css files
   * 
   * @throws UnableToCompleteException if the user has called for a .css file we
   *           can't find.
   */
  public Set<String> getCssClassNames() throws UnableToCompleteException {
    List<URL> urls = getExternalCss();
    if (cssClassNames == null) {
      final File bodyFile = getGeneratedFile();
      if (bodyFile != null) {
        try {
          urls.add(bodyFile.toURI().toURL());
        } catch (MalformedURLException e) {
          throw new RuntimeException(e);
        }
      }
      assert urls.size() > 0;

      CssStylesheet sheet = GenerateCssAst.exec(logger.getTreeLogger(),
          urls.toArray(new URL[urls.size()]));
      cssClassNames = ExtractClassNamesVisitor.exec(sheet,
          imports.toArray(new JClassType[imports.size()]));
    }
    return cssClassNames;
  }

  /**
   * @return the public interface that this CssResource implements
   */
  public JClassType getExtendedInterface() {
    return extendedInterface;
  }

  /**
   * @return the set of CssResource types whose scopes are imported
   */
  public Set<JClassType> getImports() {
    return imports;
  }

  /**
   * @return the name of this resource. This is both its method name in the
   *         owning {@link ImplicitClientBundle} and its ui:field name
   */
  public String getName() {
    return name;
  }

  /**
   * @return css class names with dashed-names normalized like so: dashedNames
   */
  public Set<String> getNormalizedCssClassNames()
      throws UnableToCompleteException {
    if (normalizedCssClassNames == null) {
      Set<String> rawNames = getCssClassNames();
      normalizedCssClassNames = new HashSet<String>();
      for (String rawName : rawNames) {
        normalizedCssClassNames.add(nameConverter.convertName(rawName));
      }
    }
    return normalizedCssClassNames;
  }

  /**
   * @return the package in which the generated CssResource interface should
   *         reside
   */
  public String getPackageName() {
    return packageName;
  }

  /**
   * @return name of the generated type
   */
  public String getQualifiedSourceName() {
    if (packageName.length() == 0) {
      return name;
    }

    return String.format("%s.%s", packageName, className);
  }

  /**
   * @return the name of the .css file(s), separate by white space
   */
  public Collection<String> getSource() {
    if (body.length() == 0) {
      return Collections.unmodifiableCollection(sources);
    }

    List<String> rtn = new ArrayList<String>(sources);
    rtn.add(getBodyFileName());
    return rtn;
  }

  private String getBodyFileName() {
    return String.format("uibinder:%s.%s.css", packageName, className);
  }

  private List<URL> getExternalCss() throws UnableToCompleteException {
    /*
     * TODO(rjrjr,bobv) refactor ResourceGeneratorUtil.findResources so we can
     * find them the same way ClientBundle does. For now, just look relative to
     * this package
     */

    ClassLoader classLoader = ImplicitCssResource.class.getClassLoader();
    String path = packageName.replace(".", "/");

    List<URL> urls = new ArrayList<URL>();

    for (String s : sources) {
      String resourcePath = path + '/' + s;
      URL found = classLoader.getResource(resourcePath);
      if (null == found) {
        logger.die("Unable to find resource: " + resourcePath);
      }
      urls.add(found);
    }
    return urls;
  }

  private File getGeneratedFile() {
    if (body.length() == 0) {
      return null;
    }

    if (generatedFile == null) {
      try {
        File f = File.createTempFile(String.format("uiBinder_%s_%s",
            packageName, className), ".css");
        f.deleteOnExit();

        BufferedWriter out = new BufferedWriter(new FileWriter(f));
        out.write(body);
        out.close();
        generatedFile = f;
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
      ResourceGeneratorUtil.addNamedFile(getBodyFileName(), generatedFile);
    }
    return generatedFile;
  }
}
