// Copyright 2015 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.devtools.build.lib.skyframe;

import static com.google.devtools.build.lib.actions.FileStateValue.FILE_STATE;
import static com.google.devtools.build.lib.skyframe.SkyFunctions.DIRECTORY_LISTING_STATE;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.FileStateValue;
import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.FileType;
import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
import java.util.EnumSet;
import java.util.Set;
import javax.annotation.Nullable;

/** Utilities for checking dirtiness of keys (mainly filesystem keys) in the graph. */
public class DirtinessCheckerUtils {
  private DirtinessCheckerUtils() {}

  static class FileDirtinessChecker extends SkyValueDirtinessChecker {
    @Override
    public boolean applies(SkyKey skyKey) {
      return skyKey.functionName().equals(FILE_STATE);
    }

    @Override
    @Nullable
    public SkyValue createNewValue(SkyKey key, @Nullable TimestampGranularityMonitor tsgm) {
      RootedPath rootedPath = (RootedPath) key.argument();
      try {
        return FileStateValue.create(rootedPath, tsgm);
      } catch (IOException e) {
        // TODO(bazel-team): An IOException indicates a failure to get a file digest or a symlink
        // target, not a missing file. Such a failure really shouldn't happen, so failing early
        // may be better here.
        return null;
      }
    }
  }

  static class DirectoryDirtinessChecker extends SkyValueDirtinessChecker {
    @Override
    public boolean applies(SkyKey skyKey) {
      return skyKey.functionName().equals(DIRECTORY_LISTING_STATE);
    }

    @Override
    @Nullable
    public SkyValue createNewValue(SkyKey key, @Nullable TimestampGranularityMonitor tsgm) {
      RootedPath rootedPath = (RootedPath) key.argument();
      try {
        return DirectoryListingStateValue.create(rootedPath);
      } catch (IOException e) {
        return null;
      }
    }
  }

  static class BasicFilesystemDirtinessChecker extends SkyValueDirtinessChecker {
    private final FileDirtinessChecker fdc = new FileDirtinessChecker();
    private final DirectoryDirtinessChecker ddc = new DirectoryDirtinessChecker();
    private final UnionDirtinessChecker checker =
        new UnionDirtinessChecker(ImmutableList.of(fdc, ddc));

    @Override
    public boolean applies(SkyKey skyKey) {
      return fdc.applies(skyKey) || ddc.applies(skyKey);
    }

    @Override
    @Nullable
    public SkyValue createNewValue(SkyKey key, @Nullable TimestampGranularityMonitor tsgm) {
      return checker.createNewValue(key, tsgm);
    }
  }

  static final class MissingDiffDirtinessChecker extends BasicFilesystemDirtinessChecker {
    private final Set<Root> missingDiffPackageRoots;

    MissingDiffDirtinessChecker(final Set<Root> missingDiffPackageRoots) {
      this.missingDiffPackageRoots = missingDiffPackageRoots;
    }

    @Override
    public boolean applies(SkyKey key) {
      return super.applies(key)
          && missingDiffPackageRoots.contains(((RootedPath) key.argument()).getRoot());
    }
  }

  /**
   * Serves for tracking whether there are external and output files {@see ExternalFilesKnowledge}.
   * Filtering of files, for which the new values should not be injected into evaluator, is done in
   * SequencedSkyframeExecutor.handleChangedFiles().
   */
  static final class ExternalDirtinessChecker extends BasicFilesystemDirtinessChecker {
    private final ExternalFilesHelper externalFilesHelper;
    private final EnumSet<FileType> fileTypesToCheck;

    ExternalDirtinessChecker(ExternalFilesHelper externalFilesHelper,
        EnumSet<FileType> fileTypesToCheck) {
      this.externalFilesHelper = externalFilesHelper;
      this.fileTypesToCheck = fileTypesToCheck;
    }

    @Override
    public boolean applies(SkyKey key) {
      if (!super.applies(key)) {
        return false;
      }
      FileType fileType = externalFilesHelper.getAndNoteFileType((RootedPath) key.argument());
      return fileTypesToCheck.contains(fileType);
    }

    @Nullable
    @Override
    public SkyValue createNewValue(SkyKey key, @Nullable TimestampGranularityMonitor tsgm) {
      throw new UnsupportedOperationException();
    }

    @Override
    public SkyValueDirtinessChecker.DirtyResult check(
        SkyKey skyKey, SkyValue oldValue, @Nullable TimestampGranularityMonitor tsgm) {
      SkyValue newValue = super.createNewValue(skyKey, tsgm);
      if (Objects.equal(newValue, oldValue)) {
        return SkyValueDirtinessChecker.DirtyResult.notDirty(oldValue);
      }
      FileType fileType = externalFilesHelper.getAndNoteFileType((RootedPath) skyKey.argument());
      if (fileType == FileType.EXTERNAL_REPO
          || fileType == FileType.EXTERNAL_IN_MANAGED_DIRECTORY) {
        // Files under output_base/external have a dependency on the WORKSPACE file, so we don't add
        // a new SkyValue to the graph yet because it might change once the WORKSPACE file has been
        // parsed.
        return SkyValueDirtinessChecker.DirtyResult.dirty(oldValue);
      }
      return SkyValueDirtinessChecker.DirtyResult.dirtyWithNewValue(oldValue, newValue);
    }
  }

  /** {@link SkyValueDirtinessChecker} that encompasses a union of other dirtiness checkers. */
  static final class UnionDirtinessChecker extends SkyValueDirtinessChecker {
    private final Iterable<SkyValueDirtinessChecker> dirtinessCheckers;

    UnionDirtinessChecker(Iterable<SkyValueDirtinessChecker> dirtinessCheckers) {
      this.dirtinessCheckers = dirtinessCheckers;
    }

    @Nullable
    private SkyValueDirtinessChecker getChecker(SkyKey key) {
      for (SkyValueDirtinessChecker dirtinessChecker : dirtinessCheckers) {
        if (dirtinessChecker.applies(key)) {
          return dirtinessChecker;
        }
      }
      return null;
    }

    @Override
    public boolean applies(SkyKey key) {
      return getChecker(key) != null;
    }

    @Override
    @Nullable
    public SkyValue createNewValue(SkyKey key, @Nullable TimestampGranularityMonitor tsgm) {
      return Preconditions.checkNotNull(getChecker(key), key).createNewValue(key, tsgm);
    }

    @Override
    public DirtyResult check(SkyKey key, @Nullable SkyValue oldValue,
        @Nullable TimestampGranularityMonitor tsgm) {
      return Preconditions.checkNotNull(getChecker(key), key).check(key, oldValue, tsgm);
    }
  }
}
