/*
 * Copyright 2000-2010 JetBrains s.r.o.
 *
 * 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.intellij.lang.ant.dom;

import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.PropertiesImplUtil;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.pom.references.PomService;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.xml.Attribute;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.DomTarget;
import com.intellij.util.xml.GenericAttributeValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;

/**
 * @author Eugene Zhuravlev
 *         Date: Apr 21, 2010
 */
public abstract class AntDomProperty extends AntDomClasspathComponent implements PropertiesProvider{
  private volatile Map<String, String> myCachedProperties;
  private volatile ClassLoader myCachedLoader;


  @Attribute("value")
  @Convert(value = AntDomPropertyValueConverter.class)
  public abstract GenericAttributeValue<Object> getValue();

  @Attribute("location")
  @Convert(value = AntPathConverter.class)
  public abstract GenericAttributeValue<PsiFileSystemItem> getLocation();

  @Attribute("resource")
  public abstract GenericAttributeValue<String> getResource();

  @Attribute("file")
  @Convert(value = AntPathValidatingConverter.class)
  public abstract GenericAttributeValue<PsiFileSystemItem> getFile();

  @Attribute("url")
  public abstract GenericAttributeValue<String> getUrl();

  @Attribute("environment")
  public abstract GenericAttributeValue<String> getEnvironment();

  @Attribute("prefix")
  public abstract GenericAttributeValue<String> getPrefix();

  @Attribute("relative")
  public abstract GenericAttributeValue<String> getRelative();

  @Attribute("basedir")
  public abstract GenericAttributeValue<String> getbasedir();

  @NotNull
  public final Iterator<String> getNamesIterator() {
    final String prefix = getPropertyPrefixValue();
    final Iterator<String> delegate = buildProperties().keySet().iterator();
    if (prefix == null) {
      return delegate;
    }
    return new Iterator<String>() {
      public boolean hasNext() {
        return delegate.hasNext();
      }

      public String next() {
        return prefix + delegate.next();
      }

      public void remove() {
        delegate.remove();
      }
    };
  }

  public PsiElement getNavigationElement(final String propertyName) {
    DomTarget domTarget = DomTarget.getTarget(this);
    if (domTarget == null) {
      final GenericAttributeValue<String> environment = getEnvironment();
      if (environment.getRawText() != null) {
        domTarget = DomTarget.getTarget(this, environment);
      }
      if (domTarget == null) {
        final GenericAttributeValue<String> resource = getResource();
        if (resource.getRawText() != null) {
          domTarget = DomTarget.getTarget(this, resource);
        }
      }
    }
    
    if (domTarget != null) {
      final PsiElement psi = PomService.convertToPsi(domTarget);
      if (psi != null) {
        return psi;
      }
    }

    final PsiFileSystemItem psiFile = getFile().getValue();
    if (psiFile != null) {
      final String prefix = getPropertyPrefixValue();
      String _propertyName = propertyName;
      if (prefix != null) {
        if (!propertyName.startsWith(prefix)) {
          return null;
        }
        _propertyName = propertyName.substring(prefix.length());
      }
      final PropertiesFile pf = toPropertiesFile(psiFile);
      if (pf != null) {
        final IProperty property = pf.findPropertyByKey(_propertyName);
        return property != null? property.getPsiElement() : null;
      }
    }
    return null;
  }

  @Nullable
  public final String getPropertyValue(String propertyName) {
    final String prefix = getPropertyPrefixValue();
    if (prefix != null) {
      if (!propertyName.startsWith(prefix)) {
        return null;
      }
      propertyName = propertyName.substring(prefix.length());
    }
    return buildProperties().get(propertyName);
  }

  private Map<String, String> buildProperties() {
    Map<String, String> result = myCachedProperties;
    if (result != null) {
      return result;
    }
    result = Collections.emptyMap();
    final String propertyName = getName().getRawText();
    if (propertyName != null) {
      final String propertyValue = getValue().getRawText();
      if (propertyValue != null) {
        result = Collections.singletonMap(propertyName, propertyValue);
      }
      else {
        String locValue = getLocation().getStringValue();
        if (locValue != null) {
          final File file = new File(locValue);
          if (!file.isAbsolute()) {
            final String baseDir = getContextAntProject().getProjectBasedirPath();
            if (baseDir != null) {
              locValue = PathUtil.getCanonicalPath(new File(baseDir, locValue).getPath());
            }
          }
          result = Collections.singletonMap(propertyName, FileUtil.toSystemDependentName(locValue));
        }
        else {
          // todo: process refid attrib if specified for the value
          final String tagText = getXmlTag().getText();
          result = Collections.singletonMap(propertyName, tagText);
        }
      }
    }
    else { // name attrib is not specified
      final PsiFileSystemItem psiFile = getFile().getValue();
      if (psiFile != null) {
        final PropertiesFile file = toPropertiesFile(psiFile);
        if (file != null) {
          result = new HashMap<String, String>();
          for (final IProperty property : file.getProperties()) {
            result.put(property.getUnescapedKey(), property.getUnescapedValue());
          }
        }
      }
      else if (getEnvironment().getRawText() != null) {
        String prefix = getEnvironment().getRawText();
        if (!prefix.endsWith(".")) {
          prefix += ".";
        }
        result = new HashMap<String, String>();
        for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
          result.put(prefix + entry.getKey(), entry.getValue());
        }
      }
      else {
        // todo: consider Url attribute?

        final String resource = getResource().getStringValue();
        if (resource != null) {
          final ClassLoader loader = getClassLoader();
          if (loader != null) {
            final InputStream stream = loader.getResourceAsStream(resource);
            if (stream != null) {
              try {
                // todo: Remote file can be XmlPropertiesFile
                final PropertiesFile propFile = (PropertiesFile)CustomAntElementsRegistry.loadContentAsFile(getXmlTag().getProject(), stream, StdFileTypes.PROPERTIES);
                result = new HashMap<String, String>();
                for (final IProperty property : propFile.getProperties()) {
                  result.put(property.getUnescapedKey(), property.getUnescapedValue());
                }
              }
              catch (IOException ignored) {
              }
            }
          }
        }
      }
    }
    return (myCachedProperties = result);
  }

  @Nullable
  public String getPropertyPrefixValue() {
    final GenericAttributeValue<String> prefixValue = getPrefix();
    if (prefixValue == null) {
      return null;
    }
    // prefix is only valid when loading from an url, file or resource
    final boolean prefixIsApplicable = (getName().getRawText() == null) && (getUrl().getRawText() != null || getFile().getRawText() != null || getResource().getRawText() != null);
    if (!prefixIsApplicable) {
      return null;
    }
    final String prefix = prefixValue.getRawText();
    if (prefix != null && !prefix.endsWith(".")) {
      return prefix + ".";
    }
    return prefix;
  }

  @Nullable
  private ClassLoader getClassLoader() {
    ClassLoader loader = myCachedLoader;
    if (loader == null) {
      myCachedLoader = loader = CustomAntElementsRegistry.createClassLoader(CustomAntElementsRegistry.collectUrls(this), getContextAntProject());
    }
    return loader;
  }

  @Nullable
  public PropertiesFile getPropertiesFile() {
    return toPropertiesFile(getFile().getValue());
  }

  @Nullable
  private static PropertiesFile toPropertiesFile(@Nullable final PsiFileSystemItem item) {
    if (item instanceof PropertiesFile) {
      return (PropertiesFile)item;
    }
    // Sometimes XmlPropertiesFile is just XmlFile, sao we should ask PropertiesImplUtil about that.
    return item instanceof PsiFile? PropertiesImplUtil.getPropertiesFile(((PsiFile)item)) : null;
  }
}
