/*
 * Copyright 2008 Google 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.google.template.soy.msgs;

import com.google.common.collect.ImmutableList;
import com.google.template.soy.internal.i18n.BidiGlobalDir;
import com.google.template.soy.msgs.restricted.SoyMsg;
import com.google.template.soy.msgs.restricted.SoyMsgPart;
import com.ibm.icu.util.ULocale;
import java.util.Iterator;
import javax.annotation.Nullable;

/**
 * Represents a full set of messages in some language/locale.
 *
 */
public abstract class SoyMsgBundle implements Iterable<SoyMsg> {
  /**
   * Gets the language/locale string of this bundle of messages.
   *
   * @return The language/locale string of the messages provided by this bundle.
   */
  @Nullable
  public abstract String getLocaleString();

  /**
   * Returns {@code true} if this is an RTL (right-to-left) locale. Subclasses are encouraged to
   * override this to provide efficient implementations.
   */
  public boolean isRtl() {
    return BidiGlobalDir.forStaticLocale(getLocaleString()) == BidiGlobalDir.RTL;
  }

  /**
   * Returns the {@link ULocale} of this message bundle. Subclasses are encouraged to override this
   * to provide efficient implementations.
   */
  @Nullable
  public ULocale getLocale() {
    return getLocaleString() == null ? null : new ULocale(getLocaleString());
  }

  /**
   * Returns the message parts, or an empty array if there is no such message.
   *
   * <p>This is useful for rendering only usecases when the rest of the {@link SoyMsg} doesn't
   * matter. The default implementation is just {@link SoyMsg#getParts} but some subclasses may have
   * more efficient implementations
   */
  public ImmutableList<SoyMsgPart> getMsgParts(long msgId) {
    SoyMsg msg = getMsg(msgId);
    return msg == null ? ImmutableList.of() : msg.getParts();
  }

  /**
   * Retrieves a message by its unique message id.
   *
   * @param msgId The message id of the message to retrieve.
   * @return The corresponding message, or null if not found.
   */
  public abstract SoyMsg getMsg(long msgId);

  /**
   * Gets the number of messages in this bundle.
   *
   * @return The number of messages in this bundle.
   */
  public abstract int getNumMsgs();

  /**
   * Returns an iterator over all the messages.
   *
   * @return An iterator over all the messages.
   */
  @Override
  public abstract Iterator<SoyMsg> iterator();

  // -----------------------------------------------------------------------------------------------
  // Null object.

  /** Null object for SoyMsgBundle, assumes English Locale. */
  public static final SoyMsgBundle EMPTY =
      new SoyMsgBundle() {

        @Override
        public String getLocaleString() {
          return "en";
        }

        @Override
        @Nullable
        public ULocale getLocale() {
          return ULocale.ENGLISH;
        }

        @Override
        public SoyMsg getMsg(long msgId) {
          return null;
        }

        @Override
        public ImmutableList<SoyMsgPart> getMsgParts(long msgId) {
          return ImmutableList.of();
        }

        @Override
        public boolean isRtl() {
          return false;
        }

        @Override
        public int getNumMsgs() {
          return 0;
        }

        @Override
        public Iterator<SoyMsg> iterator() {
          return ImmutableList.<SoyMsg>of().iterator();
        }
      };
}

@@ -3142,22 +3142,105 @@
  EMPTY =
-%0A     
+ empty(ULocale.ENGLISH);%0A%0A  public static SoyMsgBundle empty(ULocale locale) %7B%0A    return
  new Soy
@@ -3252,34 +3252,32 @@
 ndle() %7B%0A%0A      
-  
 @Override%0A      
@@ -3262,34 +3262,32 @@
       @Override%0A
-  
       public Str
@@ -3322,25 +3322,34 @@
     
-  
 return 
-%22en%22;%0A  
+locale.toString();%0A
     
@@ -3351,34 +3351,32 @@
 %0A      %7D%0A%0A      
- 
- 
 @Override%0A      
@@ -3365,26 +3365,24 @@
   @Override%0A
-  
       @Nulla
@@ -3385,18 +3385,16 @@
 ullable%0A
-  
       pu
@@ -3432,36 +3432,23 @@
     
- 
- 
 return 
-UL
+l
 ocale
-.ENGLISH;%0A  
+;%0A
     
@@ -3450,34 +3450,32 @@
 %0A      %7D%0A%0A      
- 
- 
 @Override%0A      
@@ -3460,34 +3460,32 @@
       @Override%0A
-  
       public Soy
@@ -3513,26 +3513,24 @@
 ) %7B%0A        
-  
 return null;
@@ -3528,39 +3528,35 @@
 urn null;%0A      
- 
- 
 %7D%0A%0A
-  
       @Override%0A
@@ -3547,34 +3547,32 @@
       @Override%0A
-  
       public Imm
@@ -3620,34 +3620,32 @@
 sgId) %7B%0A        
-  
 return Immutable
@@ -3653,39 +3653,35 @@
 ist.of();%0A      
-  
 %7D%0A%0A
-  
       @Override%0A
@@ -3682,26 +3682,24 @@
 rride%0A      
-  
 public boole
@@ -3715,26 +3715,24 @@
 ) %7B%0A        
-  
 return false
@@ -3731,39 +3731,35 @@
 rn false;%0A      
- 
- 
 %7D%0A%0A
-  
       @Override%0A
@@ -3750,34 +3750,32 @@
       @Override%0A
-  
       public int
@@ -3794,26 +3794,24 @@
 ) %7B%0A        
- 
- 
 return 0;%0A  
@@ -3810,31 +3810,27 @@
 rn 0;%0A      
-  
 %7D%0A%0A
-  
       @Overr
@@ -3835,26 +3835,24 @@
 rride%0A      
-  
 public Itera
@@ -3872,26 +3872,24 @@
 terator() %7B%0A
-  
         retu
@@ -3940,19 +3940,19 @@
     
-  
 %7D%0A    
+%7D;%0A
   %7D
-;
 %0A%7D%0A

Add a way to create an empty SoyMsgBundle for any locale