// 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.devtools.build.lib.rules.objc;

import static com.google.devtools.build.lib.rules.objc.AppleSkylarkCommon.BAD_SET_TYPE_ERROR;
import static com.google.devtools.build.lib.rules.objc.AppleSkylarkCommon.MISSING_KEY_ERROR;
import static com.google.devtools.build.lib.rules.objc.AppleSkylarkCommon.NOT_SET_ERROR;
import static com.google.devtools.build.lib.rules.objc.BundleableFile.BUNDLED_FIELD;
import static com.google.devtools.build.lib.rules.objc.BundleableFile.BUNDLE_PATH_FIELD;

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.packages.StructProvider;
import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.SkylarkType;
import com.google.devtools.build.lib.vfs.PathFragment;

/**
 * A utility class for converting ObjcProvider values between java and skylark representation.
 */
public class ObjcProviderSkylarkConverters {

  /**
   * A map of possible NestedSet types to the converters that should define their treatment
   * in translating between a java and skylark ObjcProvider.
   */
  private static final ImmutableMap<Class<?>, Converter> CONVERTERS =
      ImmutableMap.<Class<?>, Converter>builder()
          .put(Artifact.class, new DirectConverter())
          .put(String.class, new DirectConverter())
          .put(PathFragment.class, new PathFragmentToStringConverter())
          .put(SdkFramework.class, new SdkFrameworkToStringConverter())
          .put(BundleableFile.class, new BundleableFileToStructConverter())
          .build();

  /**
   * Returns a value for a skylark attribute given a java ObjcProvider key and value.
   */
  public static Object convertToSkylark(Key<?> javaKey, NestedSet<?> javaValue) {
    return CONVERTERS.get(javaKey.getType()).valueForSkylark(javaKey, javaValue);
  }

  /**
   * Returns a value for a java ObjcProvider given a key and a corresponding skylark value.
   */
  public static Iterable<?> convertToJava(Key<?> javaKey, Object skylarkValue) {
    return CONVERTERS.get(javaKey.getType()).valueForJava(javaKey, skylarkValue);
  }

  /**
   * Converts {@link PathFragment}s into a skylark-compatible nested set of path strings.
   */
  public static SkylarkNestedSet convertPathFragmentsToSkylark(
      Iterable<PathFragment> pathFragments) {
    NestedSetBuilder<String> result = NestedSetBuilder.stableOrder();
    for (PathFragment path : pathFragments) {
      result.add(path.getSafePathString());
    }
    return SkylarkNestedSet.of(String.class, result.build());
  }

  /**
   * A converter for ObjcProvider values.
   */
  private static interface Converter {
    /**
     * Translates a java ObjcProvider value to a skylark ObjcProvider value.
     */
    abstract Object valueForSkylark(Key<?> javaKey, NestedSet<?> javaValue);

    /**
     * Translates a skylark ObjcProvider value to a java ObjcProvider value.
     */
    abstract Iterable<?> valueForJava(Key<?> javaKey, Object skylarkValue);
  }

  /**
   * A converter that uses the same value for java and skylark.
   */
  private static class DirectConverter implements Converter {

    @Override
    public Object valueForSkylark(Key<?> javaKey, NestedSet<?> javaValue) {
      SkylarkType type = SkylarkType.of(javaKey.getType());
      return SkylarkNestedSet.of(type, javaValue);
    }

    @Override
    public Iterable<?> valueForJava(Key<?> javaKey, Object skylarkValue) {
      validateTypes(skylarkValue, javaKey.getType(), javaKey.getSkylarkKeyName());
      return ((SkylarkNestedSet) skylarkValue).toCollection();
    }
  }

  /**
   * A converter that that translates between a java PathFragment and a skylark string.
   */
  private static class PathFragmentToStringConverter implements Converter {

    @SuppressWarnings("unchecked")
    @Override
    public Object valueForSkylark(Key<?> javaKey, NestedSet<?> javaValue) {
      return convertPathFragmentsToSkylark((NestedSet<PathFragment>) javaValue);
    }

    @SuppressWarnings("unchecked")
    @Override
    public Iterable<?> valueForJava(Key<?> javaKey, Object skylarkValue) {
      validateTypes(skylarkValue, String.class, javaKey.getSkylarkKeyName());
      NestedSetBuilder<PathFragment> result = NestedSetBuilder.stableOrder();
      for (String path : ((SkylarkNestedSet) skylarkValue).toCollection(String.class)) {
        result.add(PathFragment.create(path));
      }
      return result.build();
    }
  }
  
  /**
   * A converter that that translates between a java {@link SdkFramework} and a skylark string.
   */
  private static class SdkFrameworkToStringConverter implements Converter {

    @SuppressWarnings("unchecked")
    @Override
    public Object valueForSkylark(Key<?> javaKey, NestedSet<?> javaValue) {
      NestedSetBuilder<String> result = NestedSetBuilder.stableOrder();
      for (SdkFramework framework : (Iterable<SdkFramework>) javaValue) {
        result.add(framework.getName());
      }
      return SkylarkNestedSet.of(String.class, result.build());
    }

    @SuppressWarnings("unchecked")
    @Override
    public Iterable<?> valueForJava(Key<?> javaKey, Object skylarkValue) {
      validateTypes(skylarkValue, String.class, javaKey.getSkylarkKeyName());
      NestedSetBuilder<SdkFramework> result = NestedSetBuilder.stableOrder();
      for (String path : ((SkylarkNestedSet) skylarkValue).toCollection(String.class)) {
        result.add(new SdkFramework(path));
      }
      return result.build();
    }
  }

  /**
   * A converter that that translates between a java BundleableFile and a skylark struct.
   */
  private static class BundleableFileToStructConverter implements Converter {

    @SuppressWarnings("unchecked")
    @Override
    public Object valueForSkylark(Key<?> javaKey, NestedSet<?> javaValue) {
      NestedSetBuilder<StructImpl> result = NestedSetBuilder.stableOrder();
      for (BundleableFile bundleableFile : (Iterable<BundleableFile>) javaValue) {
        result.add(
            StructProvider.STRUCT.create(
                ImmutableMap.<String, Object>of(
                    BUNDLED_FIELD, bundleableFile.getBundled(),
                    BUNDLE_PATH_FIELD, bundleableFile.getBundlePath()),
                "No such attribute '%s'"));
      }
      return SkylarkNestedSet.of(StructImpl.class, result.build());
    }

    @SuppressWarnings("unchecked")
    @Override
    public Iterable<?> valueForJava(Key<?> javaKey, Object skylarkValue) {
      validateTypes(skylarkValue, StructImpl.class, javaKey.getSkylarkKeyName());
      NestedSetBuilder<BundleableFile> result = NestedSetBuilder.stableOrder();
      for (StructImpl struct : ((SkylarkNestedSet) skylarkValue).toCollection(StructImpl.class)) {
        Artifact artifact;
        String path;
        try {
          artifact = struct.getValue(BUNDLED_FIELD, Artifact.class);
          path = struct.getValue(BUNDLE_PATH_FIELD, String.class);
        } catch (EvalException e) {
          throw new IllegalArgumentException(e.getMessage());
        }
        if (artifact == null) {
          throw new IllegalArgumentException(String.format(MISSING_KEY_ERROR, BUNDLED_FIELD));
        }
        if (path == null) {
          throw new IllegalArgumentException(String.format(MISSING_KEY_ERROR, BUNDLE_PATH_FIELD));
        }
        result.add(new BundleableFile(artifact, path));
      }
      return result.build();
    }
  }

  /**
   * Throws an error if the given object is not a nested set of the given type.
   */
  private static void validateTypes(Object toCheck, Class<?> expectedSetType, String keyName) {
    if (!(toCheck instanceof SkylarkNestedSet)) {
      throw new IllegalArgumentException(
          String.format(NOT_SET_ERROR, keyName, EvalUtils.getDataTypeName(toCheck)));
    } else if (!((SkylarkNestedSet) toCheck).getContentType().canBeCastTo(expectedSetType)) {
      throw new IllegalArgumentException(
          String.format(
              BAD_SET_TYPE_ERROR,
              keyName,
              EvalUtils.getDataTypeNameFromClass(expectedSetType),
              EvalUtils.getDataTypeNameFromClass(
                  ((SkylarkNestedSet) toCheck).getContentType().getType())));
    }
  }
}
