/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.idea.blaze.android.resources;

import com.android.resources.ResourceType;
import com.google.idea.blaze.base.experiments.BoolExperiment;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbService;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import org.jetbrains.android.augment.AndroidLightClassBase;
import org.jetbrains.android.augment.ResourceTypeClass;
import org.jetbrains.android.dom.converters.ResourceReferenceConverter;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Represents a dynamic "class R" for resources in an Android module.
 */
public class AndroidPackageRClass extends AndroidLightClassBase {
  private static final Logger LOG = Logger.getInstance(AndroidPackageRClass.class);
  private static final BoolExperiment USE_OUT_OF_CODE_MOD_COUNT = new BoolExperiment("use.out.of.code.modcount.for.r.class.cache", true);

  @NotNull
  private final PsiFile myFile;
  @NotNull
  private final String myFullyQualifiedName;
  @NotNull
  private final Module myModule;

  private CachedValue<PsiClass[]> myClassCache;

  public AndroidPackageRClass(@NotNull PsiManager psiManager,
                              @NotNull String packageName,
                              @NotNull Module module) {
    super(psiManager);

    myModule = module;
    myFullyQualifiedName = packageName + AndroidResourceClassFinder.INTERNAL_R_CLASS_SHORTNAME;
    myFile = PsiFileFactory.getInstance(myManager.getProject())
      .createFileFromText("R.java", JavaFileType.INSTANCE, "package " + packageName + ";");

    this.putUserData(ModuleUtilCore.KEY_MODULE, module);
    // Some scenarios move up to the file level and then attempt to get the module from the file.
    myFile.putUserData(ModuleUtilCore.KEY_MODULE, module);
  }

  @NotNull
  public Module getModule() {
    return myModule;
  }

  @Override
  public String toString() {
    return "AndroidPackageRClass";
  }

  @Nullable
  @Override
  public String getQualifiedName() {
    return myFullyQualifiedName;
  }

  @Override
  public String getName() {
    return "R";
  }

  @Nullable
  @Override
  public PsiClass getContainingClass() {
    return null;
  }

  @Nullable
  @Override
  public PsiFile getContainingFile() {
    return myFile;
  }

  @NotNull
  @Override
  public PsiClass[] getInnerClasses() {
    if (myClassCache == null) {
      myClassCache = CachedValuesManager.getManager(getProject())
        .createCachedValue(new CachedValueProvider<PsiClass[]>() {
          @Override
          public Result<PsiClass[]> compute() {
            return Result.create(doGetInnerClasses(),
                                 USE_OUT_OF_CODE_MOD_COUNT.getValue() ?
                                 PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT :
                                 PsiModificationTracker.MODIFICATION_COUNT);
          }
        });
    }
    return myClassCache.getValue();
  }

  private PsiClass[] doGetInnerClasses() {
    if (DumbService.isDumb(getProject())) {
      LOG.debug("R_CLASS_AUGMENT: empty because of dumb mode");
      return new PsiClass[0];
    }

    final AndroidFacet facet = AndroidFacet.getInstance(myModule);
    if (facet == null) {
      LOG.debug("R_CLASS_AUGMENT: empty because no facet");
      return new PsiClass[0];
    }

    final Set<ResourceType> types = ResourceReferenceConverter.getResourceTypesInCurrentModule(facet);
    final List<PsiClass> result = new ArrayList<PsiClass>();

    for (ResourceType type : types) {
      result.add(new ResourceTypeClass(facet, type.getName(), this));
    }
    LOG.debug("R_CLASS_AUGMENT: " + result.size() + " classes added");
    return result.toArray(new PsiClass[result.size()]);
  }

  @Override
  public PsiClass findInnerClassByName(@NonNls String name, boolean checkBases) {
    for (PsiClass aClass : getInnerClasses()) {
      if (name.equals(aClass.getName())) {
        return aClass;
      }
    }
    return null;
  }
}
