/*
 * Copyright 2013-present Facebook, 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.facebook.buck.apple.xcode;

import com.dd.plist.NSArray;
import com.dd.plist.NSDictionary;
import com.dd.plist.NSObject;
import com.dd.plist.NSString;
import com.facebook.buck.apple.xcode.xcodeproj.PBXObject;
import com.facebook.buck.apple.xcode.xcodeproj.PBXProject;
import com.facebook.buck.log.Logger;
import com.google.common.base.Preconditions;

import java.util.List;

import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;

/**
 * Serializer that handles conversion of an in-memory object graph representation of an xcode
 * project (instances of {@link PBXObject}) into an Apple property list.
 *
 * Serialization proceeds from the root object, a ${link PBXProject} instance, to all of its
 * referenced objects. Each object being visited calls back into this class ({@link #addField}) to
 * populate the plist representation with its fields.
 */
@NotThreadSafe
public class XcodeprojSerializer {
  private static final Logger LOG = Logger.get(XcodeprojSerializer.class);

  private final PBXProject rootObject;
  private final NSDictionary objects;
  private final GidGenerator gidGenerator;
  @Nullable
  private NSDictionary currentObject;

  public XcodeprojSerializer(GidGenerator gidGenerator, PBXProject project) {
    rootObject = project;
    objects = new NSDictionary();
    this.gidGenerator = gidGenerator;
  }

  /**
   * Generate a plist serialization of project bound to this serializer.
   */
  public NSDictionary toPlist() {
    serializeObject(rootObject);

    NSDictionary root = new NSDictionary();
    root.put("archiveVersion", "1");
    root.put("classes", new NSDictionary());
    root.put("objectVersion", "46");
    root.put("objects", objects);
    root.put("rootObject", rootObject.getGlobalID());

    return root;
  }

  /**
   * Serialize a {@link PBXObject} and its recursive descendants into the object dictionary.
   *
   * @return the GID of the serialized object
   *
   * @see PBXObject#serializeInto
   */
  @Nullable
  private String serializeObject(PBXObject obj) {
    if (obj.getGlobalID() == null) {
      obj.setGlobalID(obj.generateGid(gidGenerator));
      LOG.verbose("Set new object GID: %s", obj);
    } else {
      // Check that the object has already been serialized.
      NSObject object = objects.get(obj.getGlobalID());
      if (object != null) {
        LOG.verbose("Object %s found, returning existing object %s", obj, object);
        return obj.getGlobalID();
      } else {
        LOG.verbose("Object already had GID set: %s", obj);
      }
    }

    // Save the existing object being deserialized.
    NSDictionary stack = currentObject;

    currentObject = new NSDictionary();
    currentObject.put("isa", obj.isa());
    obj.serializeInto(this);
    objects.put(obj.getGlobalID(), currentObject);

    // Restore the existing object being deserialized.
    currentObject = stack;
    return obj.getGlobalID();
  }

  public void addField(String name, PBXObject obj) {
    String gid = serializeObject(obj);
    Preconditions.checkNotNull(currentObject).put(name, gid);
  }

  public void addField(String name, int val) {
    Preconditions.checkNotNull(currentObject).put(name, val);
  }

  public void addField(String name, String val) {
    Preconditions.checkNotNull(currentObject).put(name, val);
  }

  public void addField(String name, boolean val) {
    Preconditions.checkNotNull(currentObject).put(name, val);
  }

  public void addField(String name, List<? extends PBXObject> objectList) {
    NSArray array = new NSArray(objectList.size());
    for (int i = 0; i < objectList.size(); i++) {
      String gid = serializeObject(objectList.get(i));
      array.setValue(i, new NSString(gid));
    }
    Preconditions.checkNotNull(currentObject).put(name, array);
  }

  public void addField(String name, NSObject v) {
    Preconditions.checkNotNull(currentObject).put(name, v);
  }
}
